commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. release-2.2-789-ge267ac8


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-789-ge267ac8
Date: Sat, 22 Oct 2016 09:11:47 +0000 (UTC)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=e267ac86e2c3a78979fe12bdd16392f30f8d1725

The branch, master has been updated
       via  e267ac86e2c3a78979fe12bdd16392f30f8d1725 (commit)
      from  f434857b8318b05b7036025605ab18cdf3e7c238 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit e267ac86e2c3a78979fe12bdd16392f30f8d1725
Author: Sergey Poznyakoff <address@hidden>
Date:   Sat Oct 22 11:48:24 2016 +0300

    Finish conversion of MH utilities to mh_parseopt
    
    This finishes work started at commit bc73fc65.
    
    * include/mailutils/opt.h (mu_option_cache) <cache_arg>: Made const.
    * libmailutils/opt/opt.c (mu_option_cache_destroy): Don't free cache_arg.
    * doc/texinfo/mu-mh.texi: Update.
    
    * po/POTFILES.in: Remove obsolete files.
    * mh/tests/refile.at: Don't use double-dash options.
    
    * mh/mh_getopt.c (mh_opt_set_folder): New function.
    * mh/mh_getopt.h: Likewise.
    
    * mh/mhn.c: Convert to mh_getopt.
    * mh/mhparam.c: Likewise.
    * mh/mhpath.c: Likewise.
    * mh/mhseq.c: Likewise.
    * mh/msgchk.c: Likewise.
    * mh/pick.c: Likewise.
    * mh/pick.h: Likewise.
    * mh/pick.y: Likewise.
    * mh/prompter.c: Likewise.
    * mh/refile.c: Likewise.
    * mh/repl.c: Likewise.
    * mh/rmf.c: Likewise.
    * mh/rmm.c: Likewise.
    * mh/scan.c: Likewise.
    * mh/send.c: Likewise.
    * mh/show.c: Likewise.
    * mh/sortm.c: Likewise.
    * mh/whatnow.c: Likewise.
    * mh/whom.c: Likewise.

-----------------------------------------------------------------------

Summary of changes:
 doc/texinfo/mu-mh.texi  |  108 +++++-----
 include/mailutils/opt.h |    2 +-
 libmailutils/opt/opt.c  |    5 +-
 mh/mh_getopt.c          |   73 ++++++-
 mh/mh_getopt.h          |    2 +
 mh/mhn.c                |  435 ++++++++++++-----------------------------
 mh/mhparam.c            |   65 ++----
 mh/mhpath.c             |   42 +---
 mh/mhseq.c              |   60 ++----
 mh/msgchk.c             |  129 +++++-------
 mh/pick.c               |  500 +++++++++++++++++++----------------------------
 mh/pick.h               |    2 +-
 mh/pick.y               |   18 +-
 mh/prompter.c           |  123 +++---------
 mh/refile.c             |  112 ++++-------
 mh/repl.c               |  358 +++++++++++++--------------------
 mh/rmf.c                |   76 ++-----
 mh/rmm.c                |   38 +---
 mh/scan.c               |    4 +-
 mh/send.c               |  323 ++++++++++--------------------
 mh/show.c               |  177 +++++++----------
 mh/sortm.c              |  305 ++++++++++++++---------------
 mh/tests/refile.at      |    4 +-
 mh/whatnow.c            |   95 +++------
 mh/whom.c               |  113 ++++-------
 po/POTFILES.in          |    1 -
 26 files changed, 1144 insertions(+), 2026 deletions(-)

diff --git a/doc/texinfo/mu-mh.texi b/doc/texinfo/mu-mh.texi
index 406871a..1b840f9 100644
--- a/doc/texinfo/mu-mh.texi
+++ b/doc/texinfo/mu-mh.texi
@@ -27,9 +27,6 @@ distribution directory.
 @subsection Major differences between Mailutils MH and other MH implementations
 
 @enumerate 1
address@hidden All programs use usual GNU long options.  The support for MH 
single-dash
-options is provided for backward compatibility;
-
 @item UUCP addresses are not supported;
 
 @item Mailutils supports a set of new format specifications
@@ -38,6 +35,12 @@ options is provided for backward compatibility;
 @item Mailutils provides a set of new profile variables
 (@pxref{Profile Variable Diffs});
 
address@hidden All programs recognize @option{--help} and @option{--version} 
options
+
+These options are recognized only if no other arguments are present in
+the command line.  Abbreviations are not recognized.  This makes Mailutils
+MH implementation compatible with the standard usage for GNU tools.
+
 @item Several programs behave differently (@pxref{Program
 Diffs});
 
@@ -150,7 +153,7 @@ This expression is used in default @file{replcomps} and
 @deftypefn {MH Format} boolean rcpt (@samp{to} | @samp{cc} | @samp{me} | 
@samp{all})
 
 This function returns true if the given element is present in the
-recipient mask (as modified by @option{--cc} or @option{--nocc} options) and
+recipient mask (as modified by @option{-cc} or @option{-nocc} options) and
 false otherwise.  It is used in default formats for @command{repl} and
 @command{comp}, e.g.: 
 
@@ -159,7 +162,7 @@ false otherwise.  It is used in default formats for 
@command{repl} and
 @end smallexample
 
 Notice that this means that usual @file{replcomps} file will be ignoring
address@hidden and @option{--nocc} options, unless it has been modified
address@hidden and @option{-nocc} options, unless it has been modified
 as shown above. 
 @end deftypefn
 
@@ -226,12 +229,12 @@ RAND @command{anno} displays the prompt anyway.
 
 The utility is able to burst both RFC 934 digest messages and MIME
 multipart messages.  It provides two additional command line options:
address@hidden and @option{--length}.
address@hidden and @option{-length}.
 
-The @option{--recurse} option instructs the utility to recursively
+The @option{-recurse} option instructs the utility to recursively
 expand the digest.
 
-The @option{--length} option can be used to set the minimal encapsulation
+The @option{-length} option can be used to set the minimal encapsulation
 boundary length for RFC 934 digests.  Default length is 1,
 i.e. encountering one dash immediately following a newline triggers
 digest decoding.  It is OK for messages that follow RFC 934
@@ -239,12 +242,12 @@ specification.  However, many user agents do not 
precisely follow it,
 in particular, they often do not escape lines starting with a dash by
 @samp{- } sequence.  @command{Mailman} is one of such agents.  To cope
 with such digests you can set encapsulation boundary length to a higher
-value.  For example, @command{bounce --length=8} has been found to be
+value.  For example, @command{bounce -length 8} has been found to be
 sufficient for most Mailman-generated digests.
 
 @item comp
 
-Understands @option{--build} option.
+Understands @option{-build} option.
 
 @item fmtdump
 
@@ -252,24 +255,24 @@ This command is not provided.  Use @option{fmtcheck} 
instead.
 
 @item inc
 @itemize @bullet
address@hidden The @option{--moveto} option.
-The @option{--moveto} option instructs @command{inc} to move
address@hidden The @option{-moveto} option.
+The @option{-moveto} option instructs @command{inc} to move
 messages into another folder after incorporating them.  This option
-has effect only if the @option{--truncate} option has also been
+has effect only if the @option{-truncate} option has also been
 specified and the underlying mailbox supports the @samp{move}
 operation.  Currently only @samp{imap} and @samp{imaps} mailboxes
 support it.  For example, the following command moves incorporated
 messages into the @samp{archive} folder:
 
 @example
-inc --file imaps://imap.gmail.com --moveto=archive
+inc -file imaps://imap.gmail.com -moveto=archive
 @end example
 
 The @samp{moveto} URL parameter can be used instead of this option,
 e.g.:
 
 @example
-inc --file 'imaps://imap.gmail.com;moveto=archive'
+inc -file 'imaps://imap.gmail.com;moveto=archive'
 @end example
 
 @item Multiple sources
@@ -294,7 +297,7 @@ Moves incorporated messages into another folder.  This was 
discussed
 above.
 
 @item nomoveto
-Disables the previous @option{--moveto} option.
+Disables the previous @option{-moveto} option.
 
 @item address@hidden
 Controls source mailbox truncation.  If @var{bool} is not given or it is
@@ -333,13 +336,13 @@ The following format variables are silently ignored: 
@samp{center},
 @itemize @bullet
 
 @item New option
-New option @option{--compose} forces @command{mhn} editing mode.  This
+New option @option{-compose} forces @command{mhn} editing mode.  This
 is also the default mode.  This differs from the standard
 @command{mhn}, which switches to the editing mode only if no other
 options were given and the input file name coincides with the value of
 @env{mhdraft} environment variable.  
 
address@hidden Show mode (@option{--show})
address@hidden Show mode (@option{-show})
 If an appropriate mhn-show-type[/subtype] was not found, GNU @command{mhn}
 prints the decoded message content using @code{moreproc}
 variable.  Standard @command{mhn} in this case used to print @samp{don't
@@ -349,47 +352,28 @@ The default behaviour is to pipe the content to the 
standard input
 of the mhn-show-type[/subtype] command.  This is altered to using a
 temporary file if the command contains @code{%f} or @code{%F} escapes.
 
address@hidden Store mode (@option{--store})
address@hidden Store mode (@option{-store})
 If the @code{Content-Disposition} header contains @samp{filename=},
-and @command{mhn} is invoked with @option{--auto} switch, it
+and @command{mhn} is invoked with @option{-auto} switch, it
 transforms the file name into the absolute notation and uses it only
 if it lies below the current mhn-storage directory.  Standard
 @command{mhn} only requires that the file name do not begin with @samp{/}.
 
 Before saving a message part, GNU @command{mhn} checks if the file already
 exists.  If so, it asks whether the user wishes to rewrite it.  This
-behaviour is disabled when @option{--quiet} option was given.
+behaviour is disabled when @option{-quiet} option was given.
 @end itemize
 
 @item mhparam
 
-The @option{--all} mode does not display commented out entries.
+The @option{-all} mode does not display commented out entries.
 
 @item pick
 
-The command line syntax @address@hidden @var{string}}) is
-recognized only if at least one of the following conditions is met:
-
address@hidden @bullet
address@hidden The word @var{component} contains at least one capital letter.
-E.g.  @option{--User-Agent Mailutils}.
-
address@hidden The word @var{component} ends with a colon, as in
address@hidden: Mailutils}.
-
address@hidden Standard input is not connected to a terminal.
address@hidden itemize
-
-The GNU syntax for component matching is:
-
address@hidden
-pick --component @var{field} --pattern @var{string}
address@hidden smallexample
-
-New command line option @option{--cflags} allows to control the type of 
+New command line option @option{-cflags} allows to control the type of 
 regular expressions used.  The option must occur right before
address@hidden or @option{--component} option (or one of its
-aliases, like @option{--cc}, @option{--from}, etc.)
address@hidden@var{component} @var{pattern}} or equivalent construct (like
address@hidden, @option{-from}, etc.) 
 
 The argument to this option is a string of type specifications:
 
@@ -402,24 +386,24 @@ The argument to this option is a string of type 
specifications:
 
 Default is @samp{EI}.
 
-The flags remain in effect until the next occurrence of @option{--cflags}
+The flags remain in effect until the next occurrence of @option{-cflags}
 option.
 
 Sample usage:
 
 @smallexample
-pick --cflag BC --subject '*a string' 
+pick -cflag BC -subject '*a string' 
 @end smallexample
 
-The date comparison options (@option{--before} and @option{--after}
+The date comparison options (@option{-before} and @option{-after}
 accept date specifications in a wide variety of formats, e.g.:
 
 @smallexample
-pick --after 20030301
-pick --after 2003-03-01
-pick --after 01-mar-2003
-pick --after 2003-mar-01
-pick --before '1 year ago'
+pick -after 20030301
+pick -after 2003-03-01
+pick -after 01-mar-2003
+pick -after 2003-mar-01
+pick -before '1 year ago'
 etc...
 @end smallexample
 
@@ -454,11 +438,11 @@ will add it automatically.
 @item
 Linking messages between folders goes against the logic of Mailutils,
 so @command{refile} never makes links even if called with
address@hidden option.  The latter is actually a synonym for @option{--copy},
address@hidden option.  The latter is actually a synonym for @option{-copy},
 which preserves the original message.
 
 @item
-The @option{--preserve} option is not implemented.  It is retained for backward
+The @option{-preserve} option is not implemented.  It is retained for backward
 compatibility only.
 
 @item
@@ -467,7 +451,7 @@ Message specs and folder names may be interspersed.
 
 @item repl
 
-Understands @option{--use} option.  Disposition shell provides
+Understands @option{-use} option.  Disposition shell provides
 @code{use} command. 
 
 @item rmm
@@ -491,14 +475,14 @@ rmmproc:
 
 @item sortm
 
-New option @option{--numfield} specifies numeric comparison for the
+New option @option{-numfield} specifies numeric comparison for the
 given field. 
 
-Any number of @option{--datefield}, @option{--textfield} and
address@hidden options may be given, thus allowing to build sort
+Any number of @option{-datefield}, @option{-textfield} and
address@hidden options may be given, thus allowing to build sort
 criteria of arbitrary complexity. 
 
-The order of @option{--.*field} options sets the ordering priority.  This
+The order of @option{-.*field} options sets the ordering priority.  This
 differs from the behaviour of the standard @command{sortm}, which
 always orders datefield-major, textfield-minor.
 
@@ -506,11 +490,11 @@ Apart from sorting the mailfolder the following actions 
may be
 specified:
 
 @table @option
address@hidden --list
address@hidden -list
 List the ordered messages using a format string given by
address@hidden or @option{--format} option.
address@hidden or @option{-format} option.
 
address@hidden --dry-run
address@hidden -dry-run
 Do not actually sort messages, rather print what would have been
 done.  This is useful for debugging purposes.
 @end table
diff --git a/include/mailutils/opt.h b/include/mailutils/opt.h
index efecd8f..6a7f2dc 100644
--- a/include/mailutils/opt.h
+++ b/include/mailutils/opt.h
@@ -71,7 +71,7 @@ typedef struct mu_option_cache *mu_option_cache_ptr_t;
 struct mu_option_cache
 {
   struct mu_option *cache_opt;
-  char *cache_arg;
+  char const *cache_arg;
 };
 
 #define MU_PARSEOPT_DEFAULT        0
diff --git a/libmailutils/opt/opt.c b/libmailutils/opt/opt.c
index fbe2868..3a34a7f 100644
--- a/libmailutils/opt/opt.c
+++ b/libmailutils/opt/opt.c
@@ -136,7 +136,6 @@ static void
 mu_option_cache_destroy (void *ptr)
 {
   struct mu_option_cache *cache = ptr;
-  free (cache->cache_arg);
   free (cache);
 }
 
@@ -150,7 +149,7 @@ add_option_cache (struct mu_parseopt *po, struct mu_option 
*opt,
 {
   struct mu_option_cache *cache = mu_alloc (sizeof (*cache));
   cache->cache_opt = opt;
-  cache->cache_arg = arg ? mu_strdup (arg) : NULL;
+  cache->cache_arg = arg;
 
   if ((po->po_flags & MU_PARSEOPT_IMMEDIATE)
        || (opt->opt_flags & MU_OPTION_IMMEDIATE))
@@ -774,7 +773,7 @@ mu_option_set_value (struct mu_parseopt *po, struct 
mu_option *opt,
          free (errmsg);
 
          if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT))
-           exit (EXIT_ERROR);
+           exit (po->po_exit_error);
        }
     }
 }
diff --git a/mh/mh_getopt.c b/mh/mh_getopt.c
index b4d92fb..50a034c 100644
--- a/mh/mh_getopt.c
+++ b/mh/mh_getopt.c
@@ -79,6 +79,23 @@ augment_argv (int *pargc, char ***pargv)
 }
 
 static void
+process_std_options (int argc, char **argv, struct mu_parseopt *po)
+{
+  if (argc != 1)
+    return;
+  if (strcmp (argv[0], "--help") == 0)
+    {
+      mu_program_help (po, mu_strout);
+      exit (0);
+    }
+  if (strcmp (argv[0], "--version") == 0)
+    {
+      mu_program_version (po, mu_strout);
+      exit (0);
+    }
+}
+  
+static void
 process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po)
 {
   int i, j;
@@ -109,8 +126,9 @@ process_folder_arg (int *pargc, char **argv, struct 
mu_parseopt *po)
   *pargc = j;
 }
 
-static void
-set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+void
+mh_opt_set_folder (struct mu_parseopt *po, struct mu_option *opt,
+                  char const *arg)
 {
   mh_set_current_folder (arg);
 }
@@ -118,7 +136,45 @@ set_folder (struct mu_parseopt *po, struct mu_option *opt, 
char const *arg)
 static struct mu_option folder_option[] = {
   { "folder", 0, NULL, MU_OPTION_DEFAULT,
     N_("set current folder"),
-    mu_c_string, NULL, set_folder },
+    mu_c_string, NULL, mh_opt_set_folder },
+  MU_OPTION_END
+};
+
+void
+mh_version_hook (struct mu_parseopt *po, mu_stream_t stream)
+{
+  extern const char mu_version_copyright[];
+#ifdef GIT_DESCRIBE
+  mu_stream_printf (stream, "%s (GNU MH, %s) %s [%s]\n",
+                   mu_program_name, PACKAGE_NAME, PACKAGE_VERSION,
+                   GIT_DESCRIBE);
+#else
+  mu_stream_printf (stream, "%s (GNU MH, %s) %s\n", mu_program_name,
+                   PACKAGE_NAME, PACKAGE_VERSION);
+#endif
+  /* TRANSLATORS: Translate "(C)" to the copyright symbol
+     (C-in-a-circle), if this symbol is available in the user's
+     locale.  Otherwise, do not translate "(C)"; leave it as-is.  */
+  mu_stream_printf (stream, mu_version_copyright, _("(C)"));
+  mu_stream_printf (stream, _("\
+\n\
+License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to 
change and redistribute it.\n\
+There is NO WARRANTY, to the extent permitted by law.\n\
+\n\
+"));
+}
+
+static void
+fn_version (struct mu_parseopt *po, struct mu_option *opt, char const *unused)
+{
+  mu_program_version (po, mu_strout);
+  exit (0);
+}
+
+static struct mu_option version_option[] = {
+  { "version", 0, NULL, MU_OPTION_DEFAULT,
+    N_("print program version"),
+    mu_c_string, NULL, fn_version },
   MU_OPTION_END
 };
 
@@ -132,7 +188,7 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option 
*options,
   struct mu_parseopt po;
   struct mu_option *optv[3];
   struct getopt_data getopt_data;
-  char const *args[2];
+  char const *args[3];
   int flags = MU_PARSEOPT_SINGLE_DASH | MU_PARSEOPT_IMMEDIATE;
   int i;
   
@@ -177,6 +233,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option 
*options,
   //po.po_extra_info = gnu_general_help_url;
   //flags |= MU_PARSEOPT_EXTRA_INFO;
 
+  po.po_version_hook = mh_version_hook;
+  flags |= MU_PARSEOPT_VERSION_HOOK;
+  
   mu_set_program_name (argv[0]);
   mh_init ();
   augment_argv (&argc, &argv);
@@ -184,7 +243,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option 
*options,
   i = 0;
   if (mhflags & MH_GETOPT_DEFAULT_FOLDER)
     optv[i++] = folder_option;
-  optv[i++] = options;
+  if (options)
+    optv[i++] = options;
+  optv[i++] = version_option;
   optv[i] = NULL;
   
   if (mu_parseopt (&po, argc, argv, optv, flags))
@@ -193,6 +254,8 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option 
*options,
   argc -= po.po_arg_start;
   argv += po.po_arg_start;
 
+  process_std_options (argc, argv, &po);
+  
   process_folder_arg (&argc, argv, &po);
 
   if (!argdoc && argc)
diff --git a/mh/mh_getopt.h b/mh/mh_getopt.h
index b361653..2dcd57a 100644
--- a/mh/mh_getopt.h
+++ b/mh/mh_getopt.h
@@ -35,5 +35,7 @@ void mh_opt_find_file (struct mu_parseopt *po, struct 
mu_option *opt,
                       char const *arg);
 void mh_opt_read_formfile (struct mu_parseopt *po, struct mu_option *opt,
                           char const *arg);
+void mh_opt_set_folder (struct mu_parseopt *po, struct mu_option *opt,
+                       char const *arg);
 
 
diff --git a/mh/mhn.c b/mh/mhn.c
index 04f713c..1f04c6f 100644
--- a/mh/mhn.c
+++ b/mh/mhn.c
@@ -22,99 +22,9 @@
 #include <mailutils/mime.h>
 #include <setjmp.h>
 
-static char doc[] = N_("GNU MH mhn")"\v"
-N_("Options marked with `*' are not yet implemented.\n\
-Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH mhn");
 static char args_doc[] = N_("[MSGLIST]");
 
-static struct argp_option options[] = {
-  {"folder",       ARG_FOLDER,       N_("FOLDER"), 0,
-   N_("specify folder to operate upon"), 0},
-  {"file",         ARG_FILE,         N_("FILE"),   0,
-   N_("specify file to operate upon"), 0},
-
-#define GRID 10
-  {N_("MIME editing options"),   0,  NULL, OPTION_DOC,  NULL, GRID},
-  {"compose",      ARG_COMPOSE,      N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("compose the MIME message (default)"), GRID+1},
-  {"build",        0,                NULL,       OPTION_ALIAS,
-   NULL, GRID+1 },
-  {"nocompose",    ARG_NOCOMPOSE,    NULL, OPTION_HIDDEN, NULL, GRID+1},
-  {"nobuild",      ARG_NOCOMPOSE,    NULL, OPTION_HIDDEN|OPTION_ALIAS,
-   NULL, GRID+1},
-#undef GRID
-#define GRID 20  
-  {N_("Listing options"),   0,  NULL, OPTION_DOC,  NULL, GRID},
-  {"list",         ARG_LIST,         N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("list the table of contents"), GRID+1 },
-  {"nolist",       ARG_NOLIST,       NULL, OPTION_HIDDEN, "", GRID+1 },
-  {"headers",      ARG_HEADER,       N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("print the banner above the listing"), GRID+1 },
-  {"noheaders",    ARG_NOHEADERS,    NULL, OPTION_HIDDEN, "", GRID+1 },
-  {"realsize",     ARG_REALSIZE,     N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("list the decoded sizes"), GRID+1 },
-  {"norealsize",   ARG_NOREALSIZE,   NULL, OPTION_HIDDEN, "", GRID+1 },
-#undef GRID
-#define GRID 40
-  {N_("Display options"),   0,  NULL, OPTION_DOC,  NULL, GRID},
-  {"show",         ARG_SHOW,         N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("display the contents of the messages"), GRID+1},
-  {"noshow",       ARG_NOSHOW,       NULL, OPTION_HIDDEN, "", GRID+1 },
-  {"serialonly",   ARG_SERIALONLY,   N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("* display messages serially"), GRID+1},
-  {"noserialonly", ARG_NOSERIALONLY, NULL, OPTION_HIDDEN, "", GRID+1 },
-  {"form",         ARG_FORM,         N_("FILE"), 0,
-   N_("read mhl format from FILE"), GRID+1},
-  {"pause",        ARG_PAUSE,        N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("pause prior to displaying content"), GRID+1},
-  {"nopause",      ARG_NOPAUSE,      NULL, OPTION_HIDDEN, "", GRID+1 },
-#undef GRID
-#define GRID 50
-  {N_("Saving options"),   0,  NULL, OPTION_DOC,  NULL, GRID},
-  {"store",        ARG_STORE,        N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("write extracted message parts to disk"), GRID+1},
-  {"nostore",      ARG_NOSTORE,      NULL, OPTION_HIDDEN, "", GRID+1 },
-  {"auto",         ARG_AUTO,         N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("use filenames from the content headers"), GRID+1},
-  {"noauto",       ARG_NOAUTO,       NULL, OPTION_HIDDEN, "", GRID+1 },
-  {"charset",      ARG_CHARSET,      N_("NAME"), 0,
-   N_("use this charset to represent attachment file names"), GRID+1},
-#undef GRID
-#define GRID 60
-  {N_("Other options"),    0,  NULL, OPTION_DOC,  NULL, GRID},
-  {"part",         ARG_PART,         N_("PART"), 0,
-   N_("limit the scope of the operation to the given part"), GRID+1},
-  {"type",         ARG_TYPE,         N_("CONTENT"), 0,
-   N_("operate on message part with given multipart content"), GRID+1 },
-  {"verbose",      ARG_VERBOSE,     N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("print additional information"), GRID+1 },
-  {"noverbose",    ARG_NOVERBOSE,   NULL, OPTION_HIDDEN, "", GRID+1 },
-  {"quiet",        ARG_QUIET, 0, 0,
-   N_("be quiet"), GRID+1},
-#undef GRID
-  {NULL}
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "file",          MH_OPT_ARG, "filename" },
-  { "compose" },
-  { "build" },
-  { "list",          MH_OPT_BOOL },
-  { "headers",       MH_OPT_BOOL },
-  { "realsize",      MH_OPT_BOOL },
-  { "show",          MH_OPT_BOOL },
-  { "serialonly",    MH_OPT_BOOL },
-  { "form",          MH_OPT_ARG, "formfile" },
-  { "pause",         MH_OPT_BOOL },
-  { "store",         MH_OPT_BOOL },
-  { "auto",          MH_OPT_BOOL },
-  { "part",          MH_OPT_ARG, "part" },
-  { "type",          MH_OPT_ARG, "type" },
-  { "verbose",       MH_OPT_BOOL },
-  { NULL }
-};
-
 typedef struct _msg_part *msg_part_t;
 
 static msg_part_t msg_part_create (size_t num);
@@ -124,28 +34,22 @@ static void msg_part_incr (msg_part_t p);
 static void msg_part_decr (msg_part_t p);
 static void msg_part_set_subpart (msg_part_t p, size_t subpart);
 static void msg_part_print (msg_part_t p, int width);
-static msg_part_t msg_part_parse (char *str);
+static msg_part_t msg_part_parse (char const *str);
 static int msg_part_level (msg_part_t p);
 static size_t msg_part_subpart (msg_part_t p, int level);
 
-enum mhn_mode
-  {
-    mode_compose,
-    mode_list,
-    mode_show,
-    mode_store,
-  };
-
-static enum mhn_mode mode = mode_compose;
+static int compose_option;
+static int list_option; 
+static int show_option;
+static int store_option;
 
-#define OPT_HEADERS    001
-#define OPT_REALSIZE   002
-#define OPT_AUTO       004
-#define OPT_SERIALONLY 010
-#define OPT_VERBOSE    020
-#define OPT_QUIET      040
+static int headers_option = 1;
+static int realsize_option;
+static int auto_option;
+/*static int serialonly_option;*/
+static int verbose_option;
+static int quiet_option;
 
-static int mode_options = OPT_HEADERS;
 static int pause_option = -1; /* -pause option. -1 means "not given" */
 static char *formfile;
 static char *content_type;
@@ -260,173 +164,88 @@ _get_content_encoding (mu_header_t hdr, char **value)
   *value = encoding;
   return 0;
 }
-
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
+
+static void
+set_part (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
-  switch (key)
-    {
-    case ARG_FOLDER: 
-      mh_set_current_folder (arg);
-      break;
-
-    case ARG_FILE:
-      input_file = arg;
-      break;
-      
-      /* Operation mode */
-    case ARG_COMPOSE:
-      if (is_true (arg))
-       {
-         mode = mode_compose;
-         break;
-       }
-      /*FALLTHRU*/
-    case ARG_NOCOMPOSE:
-      if (mode == mode_compose)
-       mode = mode_compose;
-      break;
-
-    case ARG_LIST:
-      if (is_true (arg))
-       {
-         mode = mode_list;
-         break;
-       }
-      /*FALLTHRU*/
-    case ARG_NOLIST:
-      if (mode == mode_list)
-       mode = mode_compose;
-      break;
-
-    case ARG_SHOW:
-      if (is_true (arg))
-       {
-         mode = mode_show;
-         break;
-       }
-      /*FALLTHRU*/
-    case ARG_NOSHOW:
-      if (mode == mode_show)
-       mode = mode_compose;
-      break;
-
-    case ARG_STORE:
-      if (is_true (arg))
-       {
-         mode = mode_store;
-         break;
-       }
-      /*FALLTHRU*/
-    case ARG_NOSTORE:
-      if (mode == mode_store)
-       mode = mode_compose;
-      break;
-
-      /* List options */
-    case ARG_HEADER:
-      if (is_true (arg))
-       {
-         mode_options |= OPT_HEADERS;
-         break;
-       }
-      /*FALLTHRU*/
-    case ARG_NOHEADERS:
-      mode_options &= ~OPT_HEADERS;
-      break;
-      
-    case ARG_REALSIZE:
-      if (is_true (arg))
-       {
-         mode_options |= OPT_REALSIZE;
-         break;
-       }
-      /*FALLTHRU*/
-    case ARG_NOREALSIZE:
-      mode_options &= ~OPT_REALSIZE;
-      break;
-
-      /* Display options */
-
-    case ARG_SERIALONLY:
-      mh_opt_notimpl_warning ("-[no]serialonly");
-      if (is_true (arg))
-       {
-         mode_options |= OPT_SERIALONLY;
-         break;
-       }
-      /*FALLTHRU*/
-    case ARG_NOSERIALONLY:
-      mode_options &= ~OPT_SERIALONLY;
-      break;
-
-    case ARG_PAUSE:
-      pause_option = is_true (arg);
-      break;
-      
-    case ARG_NOPAUSE:
-      pause_option = 0;
-      break;
-
-      /* Store options */
-    case ARG_AUTO:
-      if (is_true (arg))
-       {
-         mode_options |= OPT_AUTO;
-         break;
-       }
-      /*FALLTHRU*/
-    case ARG_NOAUTO:
-      mode_options &= ~OPT_AUTO;
-      break;
-
-    case ARG_FORM:
-      mh_find_file (arg, &formfile);
-      break;
-
-      /* Common options */
-    case ARG_VERBOSE:
-      if (is_true (arg))
-       {
-         mode_options |= OPT_VERBOSE;
-         break;
-       }
-      /*FALLTHRU*/
-    case ARG_NOVERBOSE:
-      mode_options &= ~OPT_VERBOSE;
-      break;
-
-    case ARG_TYPE:
-      sfree (&content_type);
-      sfree (&content_subtype);
-      split_content (arg, &content_type, &content_subtype);
-      break;
-      
-    case ARG_PART:
-      req_part = msg_part_parse (arg);
-      break;
-
-    case ARG_QUIET:
-      mode_options |= OPT_QUIET;
-      break;
-       
-    case ARG_CHARSET:
-      charset = arg;
-      break;
-      
-    case ARGP_KEY_FINI:
-      if (!formfile)
-       mh_find_file ("mhl.headers", &formfile);
-      if (!isatty (0))
-       pause_option = 0;
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
+  req_part = msg_part_parse (arg);
 }
 
+static void
+set_type (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  sfree (&content_type);
+  sfree (&content_subtype);
+  split_content (arg, &content_type, &content_subtype);
+}
+
+static struct mu_option options[] = {
+  { "folder",      0,       N_("FOLDER"), MU_OPTION_DEFAULT,
+    N_("specify folder to operate upon"),
+    mu_c_string, NULL, mh_opt_set_folder },
+  { "file",        0,       N_("FILE"),   MU_OPTION_DEFAULT,
+    N_("specify file to operate upon"),
+    mu_c_string, &input_file },
+
+  MU_OPTION_GROUP (N_("MIME editing options")),
+  { "compose",     0,       NULL, MU_OPTION_DEFAULT,
+    N_("compose the MIME message (default)"),
+    mu_c_bool, &compose_option },
+  { "build",       0,       NULL, MU_OPTION_ALIAS },
+
+  MU_OPTION_GROUP (N_("Listing options")),
+  { "list",        0,       NULL, MU_OPTION_DEFAULT,
+    N_("list the table of contents"),
+    mu_c_bool, &list_option },
+  { "headers",     0,       NULL, MU_OPTION_DEFAULT,
+    N_("print the banner above the listing"),
+    mu_c_bool, &headers_option },
+  { "realsize",    0,       NULL, MU_OPTION_DEFAULT,
+    N_("list the decoded sizes"),
+    mu_c_bool, &realsize_option },
+
+  MU_OPTION_GROUP (N_("Display options")),
+  { "show",        0,       NULL, MU_OPTION_DEFAULT,
+    N_("display the contents of the messages"),
+    mu_c_bool, &show_option },
+  { "serialonly",  0,       NULL, MU_OPTION_HIDDEN,
+    "",
+    mu_c_bool, NULL, mh_opt_notimpl_warning },
+  { "form",        0,       N_("FILE"), MU_OPTION_DEFAULT,
+    N_("read mhl format from FILE"),
+    mu_c_string, &formfile, mh_opt_find_file },
+  { "pause",       0,       NULL, MU_OPTION_DEFAULT,
+    N_("pause prior to displaying content"),
+    mu_c_bool, &pause_option },
+
+  MU_OPTION_GROUP (N_("Saving options")),
+  { "store",        0,       NULL, MU_OPTION_DEFAULT,
+    N_("write extracted message parts to disk"),
+    mu_c_bool, &store_option },
+  { "auto",         0,       NULL, MU_OPTION_DEFAULT,
+    N_("use filenames from the content headers"),
+    mu_c_bool, &auto_option },
+  { "charset",      0,       N_("NAME"), MU_OPTION_DEFAULT,
+    N_("use this charset to represent attachment file names"),
+    mu_c_string, &charset },
+
+  MU_OPTION_GROUP (N_("Other options")),
+  { "part",         0,       N_("PART"), MU_OPTION_DEFAULT,
+    N_("limit the scope of the operation to the given part"),
+    mu_c_string, NULL, set_part },
+  { "type",         0,       N_("CONTENT"), MU_OPTION_DEFAULT,
+    N_("operate on message part with given multipart content"),
+    mu_c_string, NULL, set_type },
+  { "verbose",      0,       NULL, MU_OPTION_DEFAULT,
+    N_("print additional information"),
+    mu_c_bool, &verbose_option },
+  { "quiet",        0,       NULL, MU_OPTION_DEFAULT,
+    N_("be quiet"),
+    mu_c_bool, &quiet_option },
+
+  MU_OPTION_END
+};
+
 
 /* *********************** Message part functions ************************* */
 
@@ -555,7 +374,7 @@ msg_part_format_pool (mu_opool_t pool, msg_part_t p)
 }
 
 msg_part_t
-msg_part_parse (char *str)
+msg_part_parse (char const *str)
 {
   msg_part_t p = msg_part_create (0);
 
@@ -1267,7 +1086,7 @@ mhn_message_size (mu_message_t msg, mu_off_t *psize)
   
   *psize = 0;
   mu_message_get_body (msg, &body);
-  if (mode_options & OPT_REALSIZE)
+  if (realsize_option)
     {
       mu_stream_t dstr = NULL, bstr = NULL;
 
@@ -1389,7 +1208,7 @@ mhn_list ()
 {
   int rc; 
 
-  if (mode_options & OPT_HEADERS)
+  if (headers_option)
     printf (_(" msg part type/subtype              size  description\n"));
 
   if (message)
@@ -1672,7 +1491,7 @@ store_handler (mu_message_t msg, msg_part_t part, char 
*type, char *encoding,
   if (mu_message_is_multipart (msg, &ismime) == 0 && ismime)
     return 0;
   
-  if (mode_options & OPT_AUTO)
+  if (auto_option)
     {
       char *val;
       int rc = mu_message_aget_decoded_attachment_name (msg, charset,
@@ -1773,7 +1592,7 @@ store_handler (mu_message_t msg, msg_part_t part, char 
*type, char *encoding,
       printf (_("storing message %s part %s as file %s\n"),
              prefix, partstr, name);
 
-      if (!(mode_options & OPT_QUIET) && access (name, R_OK) == 0)
+      if (!quiet_option && access (name, R_OK) == 0)
        {
          int ok;
          
@@ -2939,17 +2758,18 @@ int
 main (int argc, char **argv)
 {
   int rc;
-  int index;
   
   MU_APP_INIT_NLS ();
   
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
-
-  argc -= index;
-  argv += index;
+  mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
+  if (!formfile)
+    mh_find_file ("mhl.headers", &formfile);
+  if (!isatty (0))
+    pause_option = 0;
 
+  if (!compose_option && !list_option && !show_option && !store_option)
+    show_option = 1;
+  
   signal (SIGPIPE, SIG_IGN);
 
   if (input_file)
@@ -2966,45 +2786,36 @@ main (int argc, char **argv)
       if (!message)
        return 1;
     }
-  else if (mode == mode_compose)
+  
+  if (compose_option)
     {
       if (argc > 1)
        {
          mu_error (_("extra arguments"));
          return 1;
        }
-      input_file = mh_expand_name (mu_folder_directory (),
-                                  argc == 1 ? argv[0] : "draft", NAME_ANY);
-      message = mh_file_to_message (NULL, input_file);
-      if (!message)
-       return 1;
+      if (!input_file)
+       {
+         input_file = mh_expand_name (mu_folder_directory (),
+                                      argc == 1
+                                        ? argv[0] : "draft", NAME_ANY);
+         message = mh_file_to_message (NULL, input_file);
+         if (!message)
+           return 1;
+       }
+      rc = mhn_compose ();
     }
   else
     {
       mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
       mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
-    }
-  
-  switch (mode)
-    {
-    case mode_compose:
-      rc = mhn_compose ();
-      break;
-      
-    case mode_list:
-      rc = mhn_list ();
-      break;
-      
-    case mode_show:
-      rc = mhn_show ();
-      break;
-      
-    case mode_store:
-      rc = mhn_store ();
-      break;
-      
-    default:
-      abort ();
+      /* FIXME: Combine the three */
+      if (list_option)
+       rc = mhn_list ();
+      if (show_option)
+       rc |= mhn_show ();
+      if (store_option)
+       rc |= mhn_store ();
     }
   return rc ? 1 : 0;
 }
diff --git a/mh/mhparam.c b/mh/mhparam.c
index b08b5d3..12733de 100644
--- a/mh/mhparam.c
+++ b/mh/mhparam.c
@@ -19,48 +19,22 @@
 
 #include <mh.h>
 
-static char doc[] = N_("GNU MH mhparam")"\v"
-N_("Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH mhparam");
 static char args_doc[] = N_("[COMPONENT [COMPONENT...]]");
 
-/* GNU options */
-static struct argp_option options[] = {
-  {"all",  ARG_ALL, NULL, 0,
-   N_("display all components from the MH profile. All other arguments are 
ignored")},
-  {"component", ARG_COMPONENT, N_("BOOL"),   OPTION_ARG_OPTIONAL,
-   N_("always display the component name") },
-  { 0 }
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "all" },
-  { "component", MH_OPT_BOOL },
-  { NULL }
-};
-
 static int display_all;
 static int display_comp_name = -1;
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
-{
-  switch (key)
-    {
-    case ARG_ALL:
-      display_all = 1;
-      break;
-      
-    case ARG_COMPONENT:
-      display_comp_name = is_true (arg);
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
+static struct mu_option options[] = {
+  { "all",  0, NULL, MU_OPTION_DEFAULT,
+    N_("display all components from the MH profile. All other arguments are 
ignored"),
+    mu_c_bool, &display_all },
+  { "component", 0, NULL, MU_OPTION_DEFAULT,
+    N_("always display the component name"),
+    mu_c_bool, &display_comp_name },
+  MU_OPTION_END
+};
+
 static struct {
   char *comp;
   char *val;
@@ -81,7 +55,8 @@ mhparam_defval (char *comp)
 }
 
 int
-mhparam_iterator (const char *comp, const char *value, void *data 
MU_ARG_UNUSED)
+mhparam_iterator (const char *comp, const char *value,
+                 void *data MU_ARG_UNUSED)
 {
   if (display_comp_name)
     printf("%s:\t", comp);
@@ -112,14 +87,10 @@ mhparam (char *comp)
 int
 main (int argc, char **argv)
 {
-  int index;
-  
   /* Native Language Support */
   MU_APP_INIT_NLS ();
 
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
+  mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
 
   if (display_all)
     {
@@ -129,11 +100,13 @@ main (int argc, char **argv)
     }
   else
     {
+      int i;
+      
       if (display_comp_name == -1)
-       display_comp_name = argc - index > 1;
+       display_comp_name = argc > 1;
        
-      for (; index < argc; index++)
-       mhparam (argv[index]);
+      for (i = 0; i < argc; i++)
+       mhparam (argv[i]);
     }
   return 0;
 }
diff --git a/mh/mhpath.c b/mh/mhpath.c
index 4da5da3..9ef8b6c 100644
--- a/mh/mhpath.c
+++ b/mh/mhpath.c
@@ -19,37 +19,9 @@
 
 #include <mh.h>
 
-static char doc[] = N_("GNU MH mhpath")"\v"
-N_("Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH mhpath");
 static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
 
-/* GNU options */
-static struct argp_option options[] = {
-  {"folder",  ARG_FOLDER, N_("FOLDER"), 0,
-   N_("specify folder to operate upon")},
-  { 0 }
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { NULL }
-};
-
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
-{
-  switch (key)
-    {
-    case ARG_FOLDER:
-      mh_set_current_folder (arg);
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
 static int
 mhpath (size_t num, mu_message_t msg, void *data)
 {
@@ -63,7 +35,6 @@ mhpath (size_t num, mu_message_t msg, void *data)
 int
 main (int argc, char **argv)
 {
-  int index = 0;
   mu_mailbox_t mbox = NULL;
   mu_url_t url = NULL;
   char *mhdir;
@@ -75,9 +46,8 @@ main (int argc, char **argv)
   /* Native Language Support */
   MU_APP_INIT_NLS ();
 
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
+  mh_getopt (&argc, &argv, NULL, MH_GETOPT_DEFAULT_FOLDER,
+            args_doc, prog_doc, NULL);
 
   current_folder = mh_current_folder ();
   /* If  the  only argument  is `+', your MH Path is output; this
@@ -98,7 +68,7 @@ main (int argc, char **argv)
 
   /* If no `msgs' are specified, mhpath outputs the folder pathname
      instead.  */
-  if (index == argc)
+  if (argc == 0)
     {
       printf ("%s\n", mhdir);
       exit (0);
@@ -112,7 +82,7 @@ main (int argc, char **argv)
      The  "new"  message  may  not be used as part of a message
      range. */
   
-  if (argc - index == 1 && strcmp (argv[index], "new") == 0)
+  if (argc == 1 && strcmp (argv[0], "new") == 0)
     {
       mu_message_t msg = NULL;
       size_t num;
@@ -126,7 +96,7 @@ main (int argc, char **argv)
   /* Mhpath  expands  and  sorts  the  message  list `msgs' and
      writes the full pathnames of the messages to the  standard
      output separated by newlines. */
-  mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
+  mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
   status = mu_msgset_foreach_message (msgset, mhpath, mhdir);
   mu_mailbox_close (mbox);
   mu_mailbox_destroy (&mbox);
diff --git a/mh/mhseq.c b/mh/mhseq.c
index d9c4d1d..142903c 100644
--- a/mh/mhseq.c
+++ b/mh/mhseq.c
@@ -18,51 +18,21 @@
 
 #include <mh.h>
 
-static char doc[] = N_("GNU MH mhseq")"\v"
-N_("Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH mhseq");
 static char args_doc[] = N_("[SEQUENCE]");
 
-static struct argp_option options[] = {
-  {"folder",  ARG_FOLDER, N_("FOLDER"), 0,
-   N_("specify the folder to use")},
-  { "uids",  'u', NULL, 0,
-    N_("show message UIDs (default)")},
-  { "numbers", 'n', NULL, 0,
-    N_("show message numbers") },
-  { NULL }
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "uid" },
-  { NULL }
-};
-
 static int uid_option = 1;
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
-{
-  switch (key)
-    {
-    case ARG_FOLDER: 
-      mh_set_current_folder (arg);
-      break;
-
-    case 'n':
-      uid_option = 0;
-      break;
-      
-    case 'u':
-      uid_option = 1;
-      break;
-
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
+static struct mu_option options[] = {
+  { "uids",   0, NULL, MU_OPTION_DEFAULT,
+    N_("show message UIDs (default)"),
+    mu_c_int, &uid_option, NULL, "1" },
+  { "numbers", 0, NULL, MU_OPTION_DEFAULT,
+    N_("show message numbers"),
+    mu_c_int, &uid_option, NULL, "0" },
+  MU_OPTION_END
+};
+
 static int
 _print_number (size_t n, void *data)
 {
@@ -73,19 +43,15 @@ _print_number (size_t n, void *data)
 int
 main (int argc, char **argv)
 {
-  int index;
   mu_mailbox_t mbox;
   mu_msgset_t msgset;
     
   /* Native Language Support */
   MU_APP_INIT_NLS ();
 
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
+  mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
+            args_doc, prog_doc, NULL);
 
-  argc -= index;
-  argv += index;
   mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
 
   mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
diff --git a/mh/msgchk.c b/mh/msgchk.c
index 3153bfd..c9f63d5 100644
--- a/mh/msgchk.c
+++ b/mh/msgchk.c
@@ -21,42 +21,9 @@
 #include "mailutils/datetime.h"
 #include <pwd.h>
 
-static char doc[] = N_("GNU MH msgchk")"\v"
-N_("Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH msgchk");
 static char args_doc[] = N_("USER [USER...]");
 
-/* GNU options */
-static struct argp_option options[] = {
-  {"date",         ARG_DATE,    N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("print out the last date mail was read") },
-  {"nodate",       ARG_NODATE,  NULL, OPTION_HIDDEN,
-   N_("don't print out the last date mail was read") },
-  {"notify",       ARG_NOTIFY, "all|mail|nomail", 0,
-   N_("produce a message upon these events") },
-  {"nonotify",     ARG_NONOTIFY, "all|mail|nomail", 0,
-   N_("disable notification") },
-  {"host",         ARG_HOST,     N_("URL"), 0,
-   N_("check mail on this host or URL") },
-  {"user",         ARG_USER,     N_("NAME"), 0,
-   N_("set user name for remote mailbox access") },
-  {"apop",         ARG_APOP,    N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("enable APOP") },
-  {"noapop",       ARG_NOAPOP,  NULL, OPTION_HIDDEN,
-   N_("disable APOP") },
-  {NULL}
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "date", MH_OPT_BOOL },
-  { "notify", MH_OPT_ARG, "all|mail|nomail" },
-  { "nonotify", MH_OPT_ARG, "all|mail|nomail" },
-  { "host", MH_OPT_ARG, "host-or-url" },
-  { "user", MH_OPT_ARG, "name" },
-  { "apop", MH_OPT_BOOL },
-  { NULL }
-};
-
 int date_option = 1;
 int apop_option;
 char *remote_host;
@@ -75,55 +42,53 @@ static struct mu_kwd notifytab[] = {
   { NULL }
 };
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
+static void
+set_notify (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
   int n;
-  
-  switch (key)
+  if (mu_kwd_xlat_name (notifytab, arg, &n))
     {
-    case ARG_DATE:
-      date_option = is_true (arg);
-      break;
-      
-    case ARG_NODATE:
-      date_option = 0;
-      break;
-      
-    case ARG_APOP:
-      apop_option = is_true (arg);
-      break;
-      
-    case ARG_NOAPOP:
-      apop_option = 0;
-      break;
-      
-    case ARG_NOTIFY:
-      if (mu_kwd_xlat_name (notifytab, arg, &n))
-       argp_error (state, "unknown notify argument: %s", arg);
-      notify |= n;
-      break;
-      
-    case ARG_NONOTIFY:
-      if (mu_kwd_xlat_name (notifytab, arg, &n))
-       argp_error (state, "unknown notify argument: %s", arg);
-      notify &= ~n;
-      break;
-      
-    case ARG_USER:
-      remote_user = arg;
-      break;
-      
-    case ARG_HOST:
-      remote_host = arg;
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
+      mu_parseopt_error (po, "unknown notify argument: %s", arg);
+      exit (po->po_exit_error);
     }
-  return 0;
+  notify |= n;
 }
 
+static void
+clr_notify (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  int n;
+  if (mu_kwd_xlat_name (notifytab, arg, &n))
+    {
+      mu_parseopt_error (po, "unknown notify argument: %s", arg);
+      exit (po->po_exit_error);
+    }
+  notify &= ~n;
+}
+  
+static struct mu_option options[] = {
+  { "date",        0,    NULL, MU_OPTION_DEFAULT,
+    N_("print out the last date mail was read"),
+    mu_c_bool, &date_option },
+  { "notify",      0, "all|mail|nomail", MU_OPTION_DEFAULT,
+    N_("produce a message upon these events"),
+    mu_c_string, NULL, set_notify },
+  { "nonotify",    0, "all|mail|nomail", MU_OPTION_DEFAULT,
+    N_("disable notification"),
+    mu_c_string, NULL, clr_notify },
+  { "host",        0,  N_("URL"), MU_OPTION_DEFAULT,
+    N_("check mail on this host or URL"),
+    mu_c_string, &remote_host },
+  { "user",        0,  N_("NAME"), MU_OPTION_DEFAULT,
+    N_("set user name for remote mailbox access"),
+    mu_c_string, &remote_user },
+  { "apop",        0,  NULL, MU_OPTION_DEFAULT,
+    N_("enable APOP"),
+    mu_c_bool, &apop_option },
+  
+  MU_OPTION_END
+};
+
 static char *
 attach_auth_ticket (mu_mailbox_t mbox)
 {
@@ -185,7 +150,7 @@ checkmail (const char *username, int personal)
     {
       static mu_url_t pop_hint;
 
-      if (pop_hint)
+      if (!pop_hint)
        {
          rc = mu_url_create (&pop_hint, "pop://");
          if (rc)
@@ -382,17 +347,11 @@ checkmail (const char *username, int personal)
 int
 main (int argc, char **argv)
 {
-  int index;
   int rc = 0;
   
   MU_APP_INIT_NLS ();
-  
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
 
-  argc -= index;
-  argv += index;
+  mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);  
 
   if (argc == 0)
     {
diff --git a/mh/pick.c b/mh/pick.c
index ac62c3a..3624267 100644
--- a/mh/pick.c
+++ b/mh/pick.c
@@ -22,119 +22,11 @@
 #include <pick.h>
 #include <pick-gram.h>
 
-static char doc[] = N_("GNU MH pick")"\v"
-N_("Compatibility syntax for picking a matching component is:\n\
-\n\
-  --Component pattern\n\
-\n\
-where Component is the component name, containing at least one capital\n\
-letter or followed by a colon, e.g.:\n\
-\n\
-  --User-Agent Mailutils\n\
-  --user-agent: Mailutils\n\
-\n\
-Use -help to obtain a list of traditional MH options.");
-static char args_doc[] = N_("[MSGLIST]");
-
-/* GNU options */
-static struct argp_option options[] = {
-#define GRID 10
-  { "folder",  ARG_FOLDER, N_("FOLDER"), 0,
-    N_("specify folder to operate upon"), GRID },
-#undef GRID
-
-#define GRID 20
-  { N_("Search patterns"), 0,  NULL, OPTION_DOC,  NULL, GRID },
-  { "component", ARG_COMPONENT, N_("FIELD"), 0,
-    N_("search the named header field"), GRID+1},
-  { "pattern", ARG_PATTERN, N_("STRING"), 0,
-    N_("set pattern to look for"), GRID+1 },
-  { "search",  0, NULL, OPTION_ALIAS, NULL, GRID+1 },
-  { "cflags",  ARG_CFLAGS,  N_("STRING"), 0,
-    N_("flags controlling the type of regular expressions. STRING must consist 
of one or more of the following letters: B=basic, E=extended, I=ignore case, 
C=case sensitive. Default is \"EI\". The flags remain in effect until the next 
occurrence of --cflags option. The option must occur right before --pattern or 
--component option (or its alias)."), GRID+1 },
-  { "cc",      ARG_CC,      N_("STRING"), 0,
-    N_("same as --component cc --pattern STRING"), GRID+1 },
-  { "date",    ARG_DATE,    N_("STRING"), 0,
-    N_("same as --component date --pattern STRING"), GRID+1 },
-  { "from",    ARG_FROM,    N_("STRING"), 0,
-    N_("same as --component from --pattern STRING"), GRID+1 },
-  { "subject", ARG_SUBJECT, N_("STRING"), 0,
-    N_("same as --component subject --pattern STRING"), GRID+1 },
-  { "to",      ARG_TO,      N_("STRING"), 0,
-    N_("same as --component to --pattern STRING"), GRID+1 },
-#undef GRID
-
-#define GRID 30  
-  { N_("Date constraint operations"), 0,  NULL, OPTION_DOC, NULL, GRID },
-  { "datefield",ARG_DATEFIELD, N_("STRING"), 0,
-    N_("search in the named date header field (default is `Date:')"), GRID+1 },
-  { "after",    ARG_AFTER,     N_("DATE"), 0,
-    N_("match messages after the given date"), GRID+1 },
-  { "before",   ARG_BEFORE,    N_("DATE"), 0,
-    N_("match messages before the given date"), GRID+1 },
-#undef GRID
-
-#define GRID 40
-  { N_("Logical operations and grouping"), 0, NULL, OPTION_DOC, NULL, GRID },
-  { "and",     ARG_AND,    NULL, 0,
-    N_("logical AND (default)"), GRID+1 },
-  { "or",      ARG_OR,     NULL, 0,
-    N_("logical OR"), GRID+1 },
-  { "not",     ARG_NOT,    NULL, 0,
-    N_("logical NOT"), GRID+1 },
-  { "lbrace",  ARG_LBRACE, NULL, 0,
-    N_("open group"), GRID+1 },
-  { "(",       0, NULL, OPTION_ALIAS, NULL, GRID+1 },
-  { "rbrace",  ARG_RBRACE, NULL, 0,
-    N_("close group"), GRID+1},
-  { ")",       0, NULL, OPTION_ALIAS, NULL, GRID+1 },
-#undef GRID
-
-#define GRID 50
-  { N_("Operations over the selected messages"), 0, NULL, OPTION_DOC, NULL,
-    GRID },
-  { "list",   ARG_LIST,       N_("BOOL"), OPTION_ARG_OPTIONAL,
-    N_("list the numbers of the selected messages (default)"), GRID+1 },
-  { "nolist", ARG_NOLIST,     NULL, OPTION_HIDDEN, "", GRID+1 },
-  { "sequence", ARG_SEQUENCE,  N_("NAME"), 0,
-    N_("add matching messages to the given sequence"), GRID+1 },
-  { "public", ARG_PUBLIC, N_("BOOL"), OPTION_ARG_OPTIONAL,
-    N_("create public sequence"), GRID+1 },
-  { "nopublic", ARG_NOPUBLIC, NULL, OPTION_HIDDEN, "", GRID+1 },
-  { "zero",     ARG_ZERO,     N_("BOOL"), OPTION_ARG_OPTIONAL,
-    N_("empty the sequence before adding messages"), GRID+1 },
-  { "nozero", ARG_NOZERO, NULL, OPTION_HIDDEN, "", GRID+1 },
-#undef GRID
-
-  { NULL }
-  
-};
+static char prog_doc[] = N_("GNU MH pick");
+static char args_doc[] = N_("[--COMPONENT PATTERN]... [MSGLIST]");
 
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "component", MH_OPT_ARG, "field" },
-  { "pattern",   MH_OPT_ARG, "pattern" },
-  { "search",    MH_OPT_ARG, "pattern" },
-  { "cc",        MH_OPT_ARG, "pattern" },
-  { "date",      MH_OPT_ARG, "pattern" },
-  { "from",      MH_OPT_ARG, "pattern" },
-  { "subject",   MH_OPT_ARG, "pattern" },
-  { "to",        MH_OPT_ARG, "pattern" },
-  { "datefield", MH_OPT_ARG, "field" },
-  { "after",     MH_OPT_ARG, "date" },
-  { "before",    MH_OPT_ARG, "date" },
-  { "and" },
-  { "or" }, 
-  { "not" },
-  { "lbrace" },
-  { "rbrace" },
-
-  { "list",      MH_OPT_BOOL },
-  { "sequence",  MH_OPT_ARG, "name" },
-  { "public",    MH_OPT_BOOL },
-  { "zero",      MH_OPT_BOOL },
-  { NULL }
-};
+static int public_option = 1;
+static int zero_option = 0;
 
 static int list = 1;
 static int seq_flags = 0; /* Create public sequences;
@@ -146,138 +38,177 @@ static mu_list_t lexlist;   /* List of input tokens */
 static mu_msgset_t picked_message_uids;
 
 static void
-add_sequence (char *name)
+add_component_name (struct mu_parseopt *po, struct mu_option *opt,
+                   char const *arg)
 {
-  if (!seq_list && mu_list_create (&seq_list))
-    {
-      mu_error (_("cannot create sequence list"));
-      exit (1);
-    }
-  mu_list_append (seq_list, name);
+  pick_add_token (&lexlist, T_COMP, arg);
+}
+
+static void
+add_component_pattern (struct mu_parseopt *po, struct mu_option *opt,
+                      char const *arg)
+{
+  pick_add_token (&lexlist, T_STRING, arg);
 }
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
+static void
+add_cflags (struct mu_parseopt *po, struct mu_option *opt,
+           char const *arg)
+{
+  pick_add_token (&lexlist, T_CFLAGS, arg);
+}
+
+static void
+add_comp_match (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  pick_add_token (&lexlist, T_COMP, opt->opt_default);
+  pick_add_token (&lexlist, T_STRING, arg);
+}
+
+static void
+add_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
-  switch (key)
+  pick_add_token (&lexlist, T_DATEFIELD, arg);
+}
+
+static void
+add_after (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  pick_add_token (&lexlist, T_AFTER, NULL);
+  pick_add_token (&lexlist, T_STRING, arg);
+}
+
+static void
+add_before (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  pick_add_token (&lexlist, T_BEFORE, NULL);
+  pick_add_token (&lexlist, T_STRING, arg);
+}
+
+static void
+add_and (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  pick_add_token (&lexlist, T_AND, NULL);
+}
+
+static void
+add_or (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  pick_add_token (&lexlist, T_OR, NULL);  
+}
+
+static void
+add_not (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  pick_add_token (&lexlist, T_NOT, NULL);
+}
+
+static void
+add_lbrace (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  pick_add_token (&lexlist, T_LBRACE, NULL);
+}
+
+static void
+add_rbrace (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  pick_add_token (&lexlist, T_RBRACE, NULL);
+}
+
+static void
+add_to_sequence (struct mu_parseopt *po, struct mu_option *opt,
+                char const *arg)
+{
+  if (!seq_list && mu_list_create (&seq_list))
     {
-    case ARG_FOLDER: 
-      mh_set_current_folder (arg);
-      break;
-
-    case ARG_SEQUENCE:
-      add_sequence (arg);
-      list = 0;
-      break;
-
-    case ARG_LIST:
-      list = is_true (arg);
-      break;
-
-    case ARG_NOLIST:
-      list = 0;
-      break;
-
-    case ARG_COMPONENT:
-      pick_add_token (&lexlist, T_COMP, arg);
-      break;
-      
-    case ARG_PATTERN:
-      pick_add_token (&lexlist, T_STRING, arg);
-      break;
-      
-    case ARG_CC:
-      pick_add_token (&lexlist, T_COMP, "cc");
-      pick_add_token (&lexlist, T_STRING, arg);
-      break;
-      
-    case ARG_DATE:           
-      pick_add_token (&lexlist, T_COMP, "date");
-      pick_add_token (&lexlist, T_STRING, arg);
-      break;
-      
-    case ARG_FROM:           
-      pick_add_token (&lexlist, T_COMP, "from");
-      pick_add_token (&lexlist, T_STRING, arg);
-      break;
-      
-    case ARG_SUBJECT:        
-      pick_add_token (&lexlist, T_COMP, "subject");
-      pick_add_token (&lexlist, T_STRING, arg);
-      break;
-      
-    case ARG_TO:
-      pick_add_token (&lexlist, T_COMP, "to");
-      pick_add_token (&lexlist, T_STRING, arg);
-      break;
-      
-    case ARG_DATEFIELD:
-      pick_add_token (&lexlist, T_DATEFIELD, arg);
-      break;
-      
-    case ARG_AFTER:
-      pick_add_token (&lexlist, T_AFTER, NULL);
-      pick_add_token (&lexlist, T_STRING, arg);
-      break;
-      
-    case ARG_BEFORE:
-      pick_add_token (&lexlist, T_BEFORE, NULL);
-      pick_add_token (&lexlist, T_STRING, arg);
-      break;
-       
-    case ARG_AND:
-      pick_add_token (&lexlist, T_AND, NULL);
-      break;
-      
-    case ARG_OR:
-      pick_add_token (&lexlist, T_OR, NULL);
-      break;
-      
-    case ARG_NOT:
-      pick_add_token (&lexlist, T_NOT, NULL);
-      break;
-
-    case ARG_LBRACE:
-      pick_add_token (&lexlist, T_LBRACE, NULL);
-      break;
-      
-    case ARG_RBRACE:
-      pick_add_token (&lexlist, T_RBRACE, NULL);
-      break;
-
-    case ARG_CFLAGS:
-      pick_add_token (&lexlist, T_CFLAGS, arg);
-      break;
-      
-    case ARG_PUBLIC:
-      if (is_true (arg))
-       seq_flags &= ~SEQ_PRIVATE;
-      else
-       seq_flags |= SEQ_PRIVATE;
-      break;
-      
-    case ARG_NOPUBLIC:
-      seq_flags |= SEQ_PRIVATE;
-      break;
-      
-    case ARG_ZERO:
-      if (is_true (arg))
-       seq_flags |= SEQ_ZERO;
-      else
-       seq_flags &= ~SEQ_ZERO;
-      break;
-
-    case ARG_NOZERO:
-      seq_flags &= ~SEQ_ZERO;
-      break;
-       
-    default:
-      return ARGP_ERR_UNKNOWN;
+      mu_error (_("cannot create sequence list"));
+      exit (1);
     }
-
-  return 0;
+  mu_list_append (seq_list, mu_strdup (arg));
+  list = 0;
 }
 
+static struct mu_option options[] = {
+  MU_OPTION_GROUP (N_("Search patterns")),
+  { "component", 0, N_("FIELD"), MU_OPTION_DEFAULT,
+    N_("search the named header field"),
+    mu_c_string, NULL, add_component_name },
+  { "pattern",   0, N_("STRING"), MU_OPTION_DEFAULT,
+    N_("set pattern to look for"),
+    mu_c_string, NULL, add_component_pattern },
+  { "search",    0, NULL, MU_OPTION_ALIAS },
+  { "cflags",    0,  N_("STRING"), MU_OPTION_DEFAULT,
+    N_("flags controlling the type of regular expressions. "
+       "STRING must consist of one or more of the following letters: "
+       "B=basic, E=extended, I=ignore case, C=case sensitive. "
+       "Default is \"EI\". The flags remain in effect until the next "
+       "occurrence of --cflags option. The option must occur right "
+       "before --pattern or --component option (or its alias)."),
+    mu_c_string, NULL, add_cflags },
+  { "cc",        0,  N_("STRING"), MU_OPTION_DEFAULT,
+    N_("search for Cc matching STRING"),
+    mu_c_string, NULL, add_comp_match, "cc" },
+  { "date",      0,  N_("STRING"), MU_OPTION_DEFAULT,
+    N_("search for Date matching STRING"),
+    mu_c_string, NULL, add_comp_match, "date" },
+  { "from",      0,  N_("STRING"), MU_OPTION_DEFAULT,
+    N_("search for From matching STRING"),
+    mu_c_string, NULL, add_comp_match, "from" },
+  { "subject",   0,  N_("STRING"), MU_OPTION_DEFAULT,
+    N_("search for Subject matching STRING"),
+    mu_c_string, NULL, add_comp_match, "subject" },
+  { "to",        0,  N_("STRING"), MU_OPTION_DEFAULT,
+    N_("search for To matching STRING"),
+    mu_c_string, NULL, add_comp_match, "to" },
+
+  MU_OPTION_GROUP (N_("Date constraint operations")),
+  { "datefield", 0, N_("STRING"), MU_OPTION_DEFAULT,
+    N_("search in the named date header field (default is `Date:')"),
+    mu_c_string, NULL, add_datefield },
+  { "after",     0, N_("DATE"), MU_OPTION_DEFAULT,
+    N_("match messages after the given date"),
+    mu_c_string, NULL, add_after },
+  { "before",    0, N_("DATE"), MU_OPTION_DEFAULT,
+    N_("match messages before the given date"),
+    mu_c_string, NULL, add_before },
+
+  MU_OPTION_GROUP (N_("Logical operations and grouping")),
+  { "and",       0, NULL, MU_OPTION_DEFAULT,
+    N_("logical AND (default)"),
+    mu_c_string, NULL, add_and },
+  { "or",        0, NULL, MU_OPTION_DEFAULT,
+    N_("logical OR"),
+    mu_c_string, NULL, add_or },
+  { "not",       0, NULL, MU_OPTION_DEFAULT,
+    N_("logical NOT"),
+    mu_c_string, NULL, add_not },
+  { "lbrace",    0, NULL, MU_OPTION_DEFAULT,
+    N_("open group"),
+    mu_c_string, NULL, add_lbrace },
+  { "(",         0, NULL, MU_OPTION_ALIAS },
+  { "rbrace",    0, NULL, MU_OPTION_DEFAULT,
+    N_("close group"),
+    mu_c_string, NULL, add_rbrace },
+  { ")",         0, NULL, MU_OPTION_ALIAS },
+
+  MU_OPTION_GROUP (N_("Operations over the selected messages")),
+  { "list",      0, NULL, MU_OPTION_ALIAS,
+    N_("list the numbers of the selected messages (default)"),
+    mu_c_bool, &list },
+  { "sequence",  0, N_("NAME"), MU_OPTION_DEFAULT,
+    N_("add matching messages to the given sequence"),
+    mu_c_string, NULL, add_to_sequence },
+  { "public",    0, NULL,       MU_OPTION_DEFAULT,
+    N_("create public sequence"),
+    mu_c_bool, &public_option },
+  { "zero",      0, NULL,       MU_OPTION_DEFAULT,
+    N_("empty the sequence before adding messages"),
+    mu_c_bool, &zero_option },
+
+  MU_OPTION_END
+  
+};
+
 static int
 pick_message (size_t num, mu_message_t msg, void *data)
 {
@@ -301,89 +232,56 @@ action_add (void *item, void *data)
   return 0;
 }
 
-void
-pick_help_hook (void)
+static void
+parse_comp_match (int *pargc, char **argv)
 {
-  printf ("\n");
-  printf (_("To match another component, use:\n\n"));
-  printf (_("  --Component pattern\n\n"));
-  printf (_("Note, that the component name must either be capitalized,\n"
-           "or followed by a colon.\n"));
-  printf ("\n");
-}
-
-/* NOTICE: For compatibility with RAND MH we have to support
-   the following command line syntax:
-
-       --COMP STRING
-
-   where `COMP' may be any string and which is equivalent to
-   `--component FIELD --pattern STRING'. Obviously this is in conflict
-   with the usual GNU long options paradigm which requires that any
-   unrecognized long option produce an error. The following
-   compromise solution is used:
-
-   The arguments `--COMP STRING' is recognized as a component matching
-   request if any of the following conditions is met:
-
-   1. The word `COMP' contains at least one capital letter.  E.g.:
+  int i, j;
+  int argc = *pargc;
 
-       --User-Agent Mailutils
-       
-   2. The word `COMP' ends with a colon, e.g.:
-
-       --user-agent: Mailutils
-   
-   3. Standard input is not connected to a terminal.  This is always
-      true when pick is invoked from mh-pick.el Emacs module.
-*/
+  for (i = j = 0; i < argc; i++)
+    {
+      if (strncmp (argv[i], "--", 2) == 0)
+       {
+         if (++i < argc)
+           {
+             pick_add_token (&lexlist, T_COMP, argv[i-1] + 2);
+             pick_add_token (&lexlist, T_STRING, argv[i]);
+           }
+         else
+           {
+             mu_error (_("%s: must be followed by a pattern"), argv[i-1]);
+             exit (1);
+           }
+       }
+      else
+       argv[j++] = argv[i];
+    }
+  argv[j] = NULL;
+  *pargc = j;
+}
 
 int
 main (int argc, char **argv)
 {
   int status;
-  int index;
   mu_mailbox_t mbox;
   mu_msgset_t msgset;
-  int interactive = mh_interactive_mode_p ();
 
   MU_APP_INIT_NLS ();
 
-  for (index = 1; index < argc; index++)
-    {
-      int colon = 0, cpos;
-      if (argv[index][0] == '-' && argv[index][1] == '-' &&
-         !strchr (argv[index], '=') &&
-         (!interactive ||
-          (colon = argv[index][cpos = strlen (argv[index]) - 1] == ':') ||
-          *mu_str_skip_class_comp (argv[index], MU_CTYPE_UPPER)) &&
-         index + 1 < argc)
-       {
-         if (colon)
-           {
-             cpos -= 2;
-             mu_asprintf (&argv[index], "--component=%*.*s", cpos, cpos,
-                          argv[index] + 2);
-           }
-         else
-           mu_asprintf (&argv[index], "--component=%s", argv[index] + 2);
-         mu_asprintf (&argv[index + 1], "--pattern=%s", argv[index + 1]);
-         index++;
-       }
-    }
-  mh_help_hook = pick_help_hook;
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option,
-                args_doc, doc, opt_handler, NULL, &index);
+  mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
+            args_doc, prog_doc, NULL);
+
+  parse_comp_match (&argc, argv);
+  
   if (pick_parse (lexlist))
     return 1;
 
+  seq_flags = (public_option ? 0 : SEQ_PRIVATE) | (zero_option ? SEQ_ZERO : 0);
+  
   mbox = mh_open_folder (mh_current_folder (),
                         seq_list ? MU_STREAM_RDWR : MU_STREAM_READ);
 
-  argc -= index;
-  argv += index;
-
   if (seq_list)
     mu_msgset_create (&picked_message_uids, NULL, MU_MSGSET_UID);
   
diff --git a/mh/pick.h b/mh/pick.h
index 75a5805..4c967b8 100644
--- a/mh/pick.h
+++ b/mh/pick.h
@@ -56,6 +56,6 @@ struct node
   } v;
 };
 
-void pick_add_token (mu_list_t *list, int tok, char *val);
+void pick_add_token (mu_list_t *list, int tok, char const *val);
 int pick_parse (mu_list_t toklist);
 int pick_eval (mu_message_t msg);
diff --git a/mh/pick.y b/mh/pick.y
index 908f9de..6c88c2c 100644
--- a/mh/pick.y
+++ b/mh/pick.y
@@ -189,28 +189,28 @@ tokname (int tok)
   switch (tok)
     {
     case T_DATEFIELD:
-      return "--datefield";
+      return "-datefield";
       
     case T_BEFORE:
-      return "--before";
+      return "-before";
       
     case T_AFTER:
-      return "--after";
+      return "-after";
       
     case T_LBRACE:
-      return "--lbrace";
+      return "-lbrace";
       
     case T_RBRACE:
-      return "--rbrace";
+      return "-rbrace";
       
     case T_OR:
-      return "--or";
+      return "-or";
       
     case T_AND:
-      return "--and";
+      return "-and";
       
     case T_NOT:
-      return "--not";
+      return "-not";
     }
   return NULL;
 }
@@ -236,7 +236,7 @@ yyerror (const char *s)
 }
   
 void
-pick_add_token (mu_list_t *list, int tok, char *val)
+pick_add_token (mu_list_t *list, int tok, char const *val)
 {
   struct token *tp;
   int rc;
diff --git a/mh/prompter.c b/mh/prompter.c
index 1d1f47b..116e102 100644
--- a/mh/prompter.c
+++ b/mh/prompter.c
@@ -19,98 +19,33 @@
 #include <mh.h>
 #include "prompter.h"
 
-static char doc[] = N_("GNU MH prompter")"\v"
-N_("Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH prompter");
 static char args_doc[] = N_("FILE");
 
-enum {
-  ARG_ERASE=256,
-  ARG_KILL,
-  ARG_PREPEND,
-  ARG_NOPREPEND,
-  ARG_RAPID,
-  ARG_NORAPID,
-  ARG_DOTEOF,
-  ARG_NODOTEOF
-};
-
-static struct argp_option options[] = {
-  { "erase",         ARG_ERASE,         N_("CHAR"), 0,
-    N_("set erase character") },
-  { "kill",          ARG_KILL,          N_("CHAR"), 0,
-    N_("set kill character") },
-  { "prepend",       ARG_PREPEND,       N_("BOOL"), 0,
-    N_("prepend user input to the message body") },
-  { "noprepend",     ARG_NOPREPEND,     NULL, OPTION_HIDDEN,
-    NULL },
-  { "rapid",         ARG_RAPID,         N_("BOOL"), 0,
-    N_("do not display message body") },
-  { "norapid",       ARG_NORAPID,       NULL, OPTION_HIDDEN,
-    NULL },
-  { "doteof",        ARG_DOTEOF,        N_("BOOL"), 0,
-    N_("a period on a line marks end-of-file") },
-  { "nodoteof",      ARG_NODOTEOF,      NULL, OPTION_HIDDEN,
-    NULL },
-  { NULL }
-};
-
-struct mh_option mh_option[] = {
-  { "erase", MH_OPT_ARG, "chr" },
-  { "kill",  MH_OPT_ARG, "chr" },
-  { "prepend", MH_OPT_BOOL },
-  { "rapid", MH_OPT_BOOL },
-  { "doteof", MH_OPT_BOOL },
-  { NULL }
-};
-
 char *erase_seq;
 char *kill_seq;
 int prepend_option;
 int rapid_option;
 int doteof_option;
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
-{
-  switch (key)
-    {
-    case ARG_ERASE:
-      erase_seq = arg;
-      break;
-      
-    case ARG_KILL:
-      kill_seq = arg;
-      break;
-      
-    case ARG_PREPEND:
-      prepend_option = is_true (arg);
-      break;
-      
-    case ARG_NOPREPEND:
-      prepend_option = 0;
-      break;
-      
-    case ARG_RAPID:
-      rapid_option = is_true (arg);
-      break;
-      
-    case ARG_NORAPID:
-      rapid_option = 0;
-      break;
-      
-    case ARG_DOTEOF:
-      doteof_option = is_true (arg);
-      break;
-      
-    case ARG_NODOTEOF:
-      doteof_option = 0;
-      break;
-
-    default:
-      return ARGP_ERR_UNKNOWN;
-   }
-  return 0;
-}
+static struct mu_option options[] = {
+  { "erase",         0,     N_("CHAR"), MU_OPTION_DEFAULT,
+    N_("set erase character"),
+    mu_c_string, &erase_seq },
+  { "kill",          0,     N_("CHAR"), MU_OPTION_DEFAULT,
+    N_("set kill character"),
+    mu_c_string, &kill_seq },
+  { "prepend",       0,     NULL, MU_OPTION_DEFAULT,
+    N_("prepend user input to the message body"),
+    mu_c_bool, &prepend_option },
+  { "rapid",         0,     NULL, MU_OPTION_DEFAULT,
+    N_("do not display message body"),
+    mu_c_bool, &rapid_option },
+  { "doteof",        0,     NULL, MU_OPTION_DEFAULT,
+    N_("a period on a line marks end-of-file"),
+    mu_c_bool, &doteof_option },
+  MU_OPTION_END
+};
 
 static int
 is_empty_string (const char *str)
@@ -142,7 +77,6 @@ mu_stream_t strout;
 int
 main (int argc, char **argv)
 {
-  int index;
   int rc;
   mu_stream_t in, tmp;
   mu_message_t msg;
@@ -156,16 +90,20 @@ main (int argc, char **argv)
   
   MU_APP_INIT_NLS ();
   
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
+  mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
 
-  if (index == argc)
+  if (argc == 0)
     {
       mu_error (_("file name not given"));
       exit (1);
     }
-  file = argv[index];
+  else if (argc > 1)
+    {
+      mu_error (_("too many arguments"));
+      exit (1);
+    }
+  
+  file = argv[0];
 
   prompter_init ();
   if (erase_seq)
@@ -178,7 +116,7 @@ main (int argc, char **argv)
       mu_error (_("cannot open stdout: %s"), mu_strerror (rc));
       return 1;
     }
-  
+
   if ((rc = mu_file_stream_create (&in, file, MU_STREAM_RDWR)))
     {
       mu_error (_("cannot open input file `%s': %s"),
@@ -186,14 +124,13 @@ main (int argc, char **argv)
       return 1;
     }
   rc = mu_stream_to_message (in, &msg);
-  mu_stream_unref (in);
   if (rc)
     {
       mu_error (_("input stream %s is not a message (%s)"),
                file, mu_strerror (rc));
       return 1;
     }
-  
+
   if ((rc = mu_temp_file_stream_create (&tmp, NULL, 0))) 
     {
       mu_error (_("Cannot open temporary file: %s"),
diff --git a/mh/refile.c b/mh/refile.c
index a522a81..36bffbf 100644
--- a/mh/refile.c
+++ b/mh/refile.c
@@ -23,39 +23,9 @@
 #include <errno.h>
 #include <fcntl.h>
 
-static char doc[] = N_("GNU MH refile")"\v"
-N_("Options marked with `*' are not yet implemented.\n\
-Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH refile");
 static char args_doc[] = N_("MSGLIST FOLDER [FOLDER...]");
 
-/* GNU options */
-static struct argp_option options[] = {
-  {"folder",  ARG_FOLDER, N_("FOLDER"), 0,
-   N_("specify folder to operate upon")},
-  {"draft",   ARG_DRAFT, NULL, 0,
-   N_("use <mh-dir>/draft as the source message")},
-  {"copy",    ARG_LINK, N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("preserve the source folder copy")},
-  {"link",    0, NULL, OPTION_ALIAS, NULL},
-  {"preserve", ARG_PRESERVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("* try to preserve message sequence numbers")},
-  {"source", ARG_SOURCE, N_("FOLDER"), 0,
-   N_("specify source folder; it will become the current folder after the 
program exits")},
-  {"src", 0, NULL, OPTION_ALIAS, NULL},
-  {"file", ARG_FILE, N_("FILE"), 0, N_("use FILE as the source message")},
-  { 0 }
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "file",     MH_OPT_ARG, "input-file"},
-  { "draft" },
-  { "link",     MH_OPT_BOOL },
-  { "preserve", MH_OPT_BOOL },
-  { "src",      MH_OPT_ARG, "folder" },
-  { NULL }
-};
-
 int link_flag = 0;
 int preserve_flag = 0;
 char *source_file = NULL;
@@ -72,9 +42,40 @@ add_folder (const char *folder)
     }
   mu_list_append (folder_name_list, mu_strdup (folder));
 }
+
+static void
+add_folder_option (struct mu_parseopt *po, struct mu_option *opt,
+                  const char *arg)
+{
+  add_folder (arg);
+}
 
+static struct mu_option options[] = {
+  { "folder",  0, N_("FOLDER"), MU_OPTION_DEFAULT,
+    N_("specify folder to operate upon"),
+    mu_c_string, NULL, add_folder_option },
+  { "draft",   0, NULL, MU_OPTION_DEFAULT,
+    N_("use <mh-dir>/draft as the source message"),
+    mu_c_string, &source_file, NULL, "draft" },
+  { "copy",    0, NULL, MU_OPTION_DEFAULT,
+    N_("preserve the source folder copy"),
+    mu_c_bool, &link_flag },
+  { "link",    0, NULL, MU_OPTION_ALIAS },
+  { "preserve", 0, NULL, MU_OPTION_HIDDEN,
+    N_("try to preserve message sequence numbers"),
+    mu_c_string, NULL, mh_opt_notimpl_warning },
+  { "source", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
+    N_("specify source folder; it will become the current folder after the 
program exits"),
+    mu_c_string, NULL, mh_opt_set_folder },
+  { "src", 0, NULL, MU_OPTION_ALIAS },
+  { "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
+    N_("use FILE as the source message"),
+    mu_c_string, &source_file },
+  MU_OPTION_END
+};
+
 void
-open_folders ()
+open_folders (void)
 {
   int rc;
   mu_iterator_t itr;
@@ -139,47 +140,11 @@ _close_folder (void *unused, mu_mailbox_t mbox)
 }
 
 void
-close_folders ()
+close_folders (void)
 {
   enumerate_folders (_close_folder, NULL);
 }
 
-static int
-opt_handler (int key, char *arg, struct argp_state *state)
-{
-  switch (key)
-    {
-    case ARG_FOLDER: 
-      add_folder (arg);
-      break;
-
-    case ARG_DRAFT:
-      source_file = "draft";
-      break;
-
-    case ARG_LINK:
-      link_flag = is_true(arg);
-      break;
-      
-    case ARG_PRESERVE:
-      mh_opt_notimpl_warning ("-preserve");
-      preserve_flag = is_true(arg);
-      break;
-       
-    case ARG_SOURCE:
-      mh_set_current_folder (arg);
-      break;
-      
-    case ARG_FILE:
-      source_file = arg;
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
 void
 refile_folder (void *data, mu_mailbox_t mbox)
 {
@@ -216,7 +181,6 @@ refile_iterator (size_t num, mu_message_t msg, void *data)
 int
 main (int argc, char **argv)
 {
-  int index;
   mu_msgset_t msgset;
   mu_mailbox_t mbox;
   int status, i, j;
@@ -224,13 +188,7 @@ main (int argc, char **argv)
   /* Native Language Support */
   MU_APP_INIT_NLS ();
 
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
-
-  argc -= index;
-  argv += index;
-
+  mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
   /* Collect any surplus folders */
   for (i = j = 0; i < argc; i++)
     {
diff --git a/mh/repl.c b/mh/repl.c
index 0ab11f4..826ecaf 100644
--- a/mh/repl.c
+++ b/mh/repl.c
@@ -22,89 +22,9 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-static char doc[] = N_("GNU MH repl")"\v"
-N_("Options marked with `*' are not yet implemented.\n\
-Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH repl");
 static char args_doc[] = N_("[+FOLDER] [MESSAGE]");
 
-
-/* GNU options */
-static struct argp_option options[] = {
-  {"annotate", ARG_ANNOTATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("add Replied: header to the message being replied to")},
-  {"build",   ARG_BUILD, 0, 0,
-   N_("build the draft and quit immediately")},
-  {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
-   N_("specify the folder for message drafts")},
-  {"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0,
-   N_("undo the effect of the last --draftfolder option")},
-  {"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0,
-   N_("invoke the draftmessage facility")},
-  {"cc", ARG_CC, "{all|to|cc|me}", 0,
-   N_("specify whom to place on the Cc: list of the reply")},
-  {"nocc", ARG_NOCC, "{all|to|cc|me}", 0,
-   N_("specify whom to remove from the Cc: list of the reply")},
-  {"folder",  ARG_FOLDER, N_("FOLDER"), 0, N_("specify folder to operate 
upon")},
-  {"group",  ARG_GROUP,  N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("construct a group or followup reply") },
-  {"editor", ARG_EDITOR, N_("PROG"), 0, N_("set the editor program to use")},
-  {"noedit", ARG_NOEDIT, 0, 0, N_("suppress the initial edit")},
-  {"fcc",    ARG_FCC, N_("FOLDER"), 0, N_("set the folder to receive Fcc's")},
-  {"filter", ARG_FILTER, N_("MHL-FILTER"), 0,
-   N_("set the mhl filter to preprocess the body of the message being 
replied")},
-  {"form",   ARG_FORM, N_("FILE"), 0, N_("read format from given file")},
-  {"format", ARG_FORMAT, N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("include a copy of the message being replied; the message will be 
processed using either the default filter \"mhl.reply\", or the filter 
specified by --filter option") },
-  {"noformat", ARG_NOFORMAT, 0,          OPTION_HIDDEN, "" },
-  {"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("* annotate the message in place")},
-  {"query", ARG_QUERY, N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("* query for addresses to place in To: and Cc: lists")},
-  {"width", ARG_WIDTH, N_("NUMBER"), 0, N_("set output width")},
-  {"whatnowproc", ARG_WHATNOWPROC, N_("PROG"), 0,
-   N_("set the replacement for whatnow program")},
-  {"nowhatnowproc", ARG_NOWHATNOWPROC, NULL, 0,
-   N_("don't run whatnowproc")},
-  {"use", ARG_USE, N_("BOOL"), OPTION_ARG_OPTIONAL, N_("use draft file 
preserved after the last session") },
-  { 0 }
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "annotate",    MH_OPT_BOOL },
-  { "build" },
-  { "cc",          MH_OPT_ARG, "all/to/cc/me"},
-  { "nocc",        MH_OPT_ARG, "all/to/cc/me"},
-  { "form",        MH_OPT_ARG, "formatfile"},
-  { "width",       MH_OPT_ARG, "number"},
-  { "draftfolder", MH_OPT_ARG, "folder"},
-  { "nodraftfolder" },
-  { "draftmessage" },
-  { "editor", MH_OPT_ARG, "program"},
-  { "noedit" },
-  { "fcc",         MH_OPT_ARG, "folder"},
-  { "filter",      MH_OPT_ARG, "program"},
-  { "format",      MH_OPT_BOOL },
-  { "group",       MH_OPT_BOOL },
-  { "inplace",     MH_OPT_BOOL },
-  { "query",       MH_OPT_BOOL },
-  { "whatnowproc", MH_OPT_ARG, "program"},
-  { "nowhatnowproc" },
-  { NULL }
-};
-
-static char default_format_str[] =
-"%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)"
-"%<(nonnull)%(void(width))%(putaddr To: )\\n%>"
-"%(lit)%<(rcpt to)%(formataddr{to})%>%<(rcpt cc)%(formataddr{cc})%>%<(rcpt 
me)%(formataddr(me))%>"
-"%<(nonnull)%(void(width))%(putaddr cc: )\\n%>"
-"%<{fcc}Fcc: %{fcc}\\n%>"
-"%<{subject}Subject: Re: %(unre{subject})\\n%>"
-"%(lit)%(concat(in_reply_to))%<(nonnull)%(void(width))%(printhdr In-reply-to: 
)\\n%>"
-"%(lit)%(concat(references))%<(nonnull)%(void(width))%(printhdr References: 
)\\n%>"
-"X-Mailer: MH \\(%(package_string)\\)\\n" 
-"--------\n";
-
 static char *format_str = NULL;
 static mh_format_t format;
 static int width = 80;
@@ -114,12 +34,11 @@ static int initial_edit = 1;
 static const char *whatnowproc;
 static mu_msgset_t msgset;
 static mu_mailbox_t mbox;
-static int build_only = 0; /* --build flag */
-static int nowhatnowproc = 0; /* --nowhatnowproc */
-static int query_mode = 0; /* --query flag */
-static int use_draft = 0;  /* --use flag */
-static char *mhl_filter = NULL; /* --filter flag */
-static int annotate;       /* --annotate flag */
+static int build_only = 0; /* -build flag */
+static int nowhatnowproc = 0; /* -nowhatnowproc */
+static int use_draft = 0;  /* -use flag */
+static char *mhl_filter = NULL; /* -filter flag */
+static int annotate;       /* -annotate flag */
 static char *draftmessage = "new";
 static const char *draftfolder = NULL;
 static mu_opool_t fcc_pool;
@@ -136,146 +55,136 @@ decode_cc_flag (const char *opt, const char *arg)
     }
   return rc;
 }
+
+static void
+set_cc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  rcpt_mask |= decode_cc_flag ("-cc", arg);
+}
+
+static void
+clr_cc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  rcpt_mask &= ~decode_cc_flag ("-nocc", arg);
+}
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
+static void
+set_fcc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
-  switch (key)
+  if (!has_fcc)
     {
-    case ARGP_KEY_INIT:
-      draftfolder = mh_global_profile_get ("Draft-Folder", NULL);
-      whatnowproc = mh_global_profile_get ("whatnowproc", NULL);
-      break;
-      
-    case ARG_ANNOTATE:
-      annotate = is_true (arg);
-      break;
-      
-    case ARG_BUILD:
-      build_only = 1;
-      break;
-      
-    case ARG_CC:
-      rcpt_mask |= decode_cc_flag ("-cc", arg);
-      break;
+      mu_opool_create (&fcc_pool, 1);
+      has_fcc = 1;
+    }
+  else
+    mu_opool_append (fcc_pool, ", ", 2);
+  mu_opool_appendz (fcc_pool, arg);
+}
 
-    case ARG_NOCC:
-      rcpt_mask &= ~decode_cc_flag ("-nocc", arg);
-      break;
-       
-    case ARG_DRAFTFOLDER:
-      draftfolder = arg;
-      break;
-      
-    case ARG_EDITOR:
-      wh_env.editor = arg;
-      break;
-      
-    case ARG_FOLDER: 
-      mh_set_current_folder (arg);
-      break;
+static void
+set_whatnowproc (struct mu_parseopt *po, struct mu_option *opt,
+                char const *arg)
+{
+  whatnowproc = mu_strdup (arg);
+  nowhatnowproc = 0;
+}
 
-    case ARG_FORM:
+static void
+set_group (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  if (strcmp (arg, "1") == 0)
+    {
+      if (mh_read_formfile ("replgroupcomps", &format_str))
+       exit (1);
+      rcpt_mask |= RCPT_ALL;
+    }
+  else
+    {
       free (format_str);
       format_str = NULL;
-      if (mh_read_formfile (arg, &format_str))
-       exit (1);
-      break;
-
-    case ARG_GROUP:
-      if (is_true (arg))
-       {
-         if (mh_read_formfile ("replgroupcomps", &format_str))
-           exit (1);
-         rcpt_mask |= RCPT_ALL;
-       }
-      else
-       {
-         free (format_str);
-         format_str = NULL;
-       }
-      break;
-           
-    case ARG_DRAFTMESSAGE:
-      draftmessage = arg;
-      break;
-
-    case ARG_USE:
-      use_draft = is_true (arg);
-      break;
-      
-    case ARG_WIDTH:
-      width = strtoul (arg, NULL, 0);
-      if (!width)
-       {
-         argp_error (state, _("invalid width"));
-         exit (1);
-       }
-      break;
-
-    case ARG_NODRAFTFOLDER:
-      draftfolder = NULL;
-      break;
-
-    case ARG_NOEDIT:
-      initial_edit = 0;
-      break;
-      
-    case ARG_QUERY:
-      query_mode = is_true (arg);
-      if (query_mode)
-       mh_opt_notimpl_warning ("-query");
-      break;
-      
-    case ARG_FILTER:
-      mh_find_file (arg, &mhl_filter);
-      break;
-
-    case ARG_FORMAT:
-      if (is_true (arg))
-       mh_find_file ("mhl.repl", &mhl_filter);
-      else
-       mhl_filter = NULL;
-      break;
-
-    case ARG_NOFORMAT:
-      mhl_filter = NULL;
-      break;
-      
-    case ARG_FCC:
-      if (!has_fcc)
-       {
-         mu_opool_create (&fcc_pool, 1);
-         has_fcc = 1;
-       }
-      else
-       mu_opool_append (fcc_pool, ", ", 2);
-      mu_opool_appendz (fcc_pool, arg);
-      break;
-         
-    case ARG_INPLACE:
-      mh_opt_notimpl_warning ("-inplace");
-      break;
-      
-    case ARG_WHATNOWPROC:
-      whatnowproc = arg;
-      break;
-
-    case ARG_NOWHATNOWPROC:
-      nowhatnowproc = 1;
-      break;
-
-    case ARGP_KEY_FINI:
-      if (!format_str)
-       format_str = default_format_str;
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
     }
-  return 0;
 }
 
+static struct mu_option options[] = {
+  { "annotate", 0, NULL, MU_OPTION_DEFAULT,
+    N_("add Replied: header to the message being replied to"),
+    mu_c_bool, &annotate },
+  { "build",    0, NULL, MU_OPTION_DEFAULT,
+    N_("build the draft and quit immediately"),
+    mu_c_bool, &build_only },
+  { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
+    N_("specify the folder for message drafts"),
+    mu_c_string, &draftfolder },
+  { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
+    N_("undo the effect of the last --draftfolder option"),
+    mu_c_string, &draftfolder, mh_opt_clear_string },
+  { "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT,
+    N_("invoke the draftmessage facility"),
+    mu_c_string, &draftmessage },
+  { "cc", 0, "{all|to|cc|me}", 0,
+    N_("specify whom to place on the Cc: list of the reply"),
+    mu_c_string, NULL, set_cc },
+  { "nocc", 0, "{all|to|cc|me}", 0,
+    N_("specify whom to remove from the Cc: list of the reply"),
+    mu_c_string, NULL, clr_cc },
+  { "group", 0,  NULL, MU_OPTION_DEFAULT,
+    N_("construct a group or followup reply"),
+    mu_c_string, NULL, set_group },
+  { "editor", 0, N_("PROG"), MU_OPTION_DEFAULT,
+    N_("set the editor program to use"),
+    mu_c_string, &wh_env.editor },
+  { "noedit", 0, NULL, MU_OPTION_DEFAULT,
+    N_("suppress the initial edit"),
+    mu_c_int, &initial_edit, NULL, "0" },
+  { "fcc",    0, N_("FOLDER"), MU_OPTION_DEFAULT,
+    N_("set the folder to receive Fcc's"),
+    mu_c_string, NULL, set_fcc },
+  { "filter", 0, N_("MHL-FILTER"), MU_OPTION_DEFAULT,
+    N_("set the mhl filter to preprocess the body of the message being 
replied"),
+    mu_c_string, &mhl_filter, mh_opt_find_file },
+  { "form",   0, N_("FILE"), MU_OPTION_DEFAULT,
+    N_("read format from given file") ,
+    mu_c_string, &format_str, mh_opt_read_formfile },
+  { "format", 0, NULL, MU_OPTION_DEFAULT,
+    N_("include a copy of the message being replied; the message will be 
processed using either the default filter \"mhl.reply\", or the filter 
specified by --filter option"),
+    mu_c_string, &mhl_filter, mh_opt_find_file, "mhl.repl" },
+  { "noformat", 0, NULL,   MU_OPTION_DEFAULT,
+    N_("cancels the effect of the recent -format option"),
+    mu_c_string, &mhl_filter, mh_opt_clear_string },
+  { "inplace",  0, NULL,   MU_OPTION_HIDDEN,
+    N_("annotate the message in place"),
+    mu_c_string, NULL, mh_opt_notimpl_warning },
+  { "query",    0, NULL,   MU_OPTION_HIDDEN,
+    N_("query for addresses to place in To: and Cc: lists"),
+    mu_c_string, NULL, mh_opt_notimpl_warning },
+  { "width",    0, N_("NUMBER"), MU_OPTION_DEFAULT,
+    N_("set output width"),
+    mu_c_int, &width },
+  { "whatnowproc", 0, N_("PROG"), MU_OPTION_DEFAULT,
+    N_("set the replacement for whatnow program"),
+    mu_c_string, NULL, set_whatnowproc },
+  { "nowhatnowproc", 0, NULL, MU_OPTION_DEFAULT,
+    N_("don't run whatnowproc"),
+    mu_c_int, &nowhatnowproc, NULL, "1" },
+  { "use", 0, NULL, MU_OPTION_DEFAULT,
+    N_("use draft file preserved after the last session"),
+    mu_c_bool, &use_draft },
+  
+  MU_OPTION_END
+};
+
+static char default_format_str[] =
+"%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)"
+"%<(nonnull)%(void(width))%(putaddr To: )\\n%>"
+"%(lit)%<(rcpt to)%(formataddr{to})%>%<(rcpt cc)%(formataddr{cc})%>%<(rcpt 
me)%(formataddr(me))%>"
+"%<(nonnull)%(void(width))%(putaddr cc: )\\n%>"
+"%<{fcc}Fcc: %{fcc}\\n%>"
+"%<{subject}Subject: Re: %(unre{subject})\\n%>"
+"%(lit)%(concat(in_reply_to))%<(nonnull)%(void(width))%(printhdr In-reply-to: 
)\\n%>"
+"%(lit)%(concat(references))%<(nonnull)%(void(width))%(printhdr References: 
)\\n%>"
+"X-Mailer: MH \\(%(package_string)\\)\\n" 
+"--------\n";
+
 void
 make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
 {
@@ -396,15 +305,20 @@ make_draft (mu_mailbox_t mbox, int disp, struct 
mh_whatnow_env *wh)
 int
 main (int argc, char **argv)
 {
-  int index, rc;
+  int rc;
 
   /* Native Language Support */
   MU_APP_INIT_NLS ();
 
-  mh_argp_init ();
+  draftfolder = mh_global_profile_get ("Draft-Folder", NULL);
+  whatnowproc = mh_global_profile_get ("whatnowproc", NULL);
+
+  mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
+            args_doc, prog_doc, NULL);
+
+  if (!format_str)
+    format_str = default_format_str;
 
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
   if (mh_format_parse (format_str, &format))
     {
       mu_error (_("Bad format string"));
@@ -412,7 +326,7 @@ main (int argc, char **argv)
     }
 
   mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
-  mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
+  mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
   if (!mh_msgset_single_message (msgset))
     {
       mu_error (_("only one message at a time!"));
diff --git a/mh/rmf.c b/mh/rmf.c
index 2e8c47f..91d66af 100644
--- a/mh/rmf.c
+++ b/mh/rmf.c
@@ -28,29 +28,9 @@
 
 #include <dirent.h>
 
-static char doc[] = N_("GNU MH rmf")"\v"
-N_("Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH rmf");
 static char args_doc[] = N_("[+FOLDER]");
 
-/* GNU options */
-static struct argp_option options[] = {
-  {"folder",  ARG_FOLDER, N_("FOLDER"), 0,
-   N_("specify the folder to delete")},
-  {"interactive", ARG_INTERACTIVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
-    N_("interactive mode: ask for confirmation before removing each folder")},
-  {"nointeractive", ARG_NOINTERACTIVE, NULL, OPTION_HIDDEN, ""},
-  {"recursive", ARG_RECURSIVE, NULL, 0,
-   N_("recursively delete all subfolders")},
-  {"norecursive", ARG_NORECURSIVE, NULL, OPTION_HIDDEN, ""},
-  { 0 }
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "interactive", MH_OPT_BOOL },
-  { 0 }
-};
-
 int explicit_folder; /* Was the folder explicitly given */
 int interactive; /* Ask for confirmation before deleting */
 int recursive;     /* Recursively process all the sub-directories */
@@ -59,38 +39,26 @@ static char *cur_folder_path; /* Full pathname of the 
current folder */
 static char *folder_name;     /* Name of the (topmost) folder to be
                                 deleted */
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
+static void
+set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
-  switch (key)
-    {
-    case ARG_FOLDER:
-      explicit_folder = 1;
-      folder_name = arg;
-      break;
-
-    case ARG_INTERACTIVE:
-      interactive = is_true (arg);
-      break;
-
-    case ARG_NOINTERACTIVE:
-      interactive = 0;
-      break;
-       
-    case ARG_RECURSIVE:
-      recursive = is_true (arg);
-      break;
-      
-    case ARG_NORECURSIVE:
-      recursive = 0;
-      break;
-
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
+  explicit_folder = 1;
+  folder_name = mu_strdup (arg);
+} 
+
+static struct mu_option options[] = {
+  { "folder",  0, N_("FOLDER"), MU_OPTION_DEFAULT,
+    N_("specify the folder to delete"),
+    mu_c_string, NULL, set_folder },
+  { "interactive", 0, NULL, MU_OPTION_DEFAULT,
+    N_("interactive mode: ask for confirmation before removing each folder"),
+    mu_c_bool, &interactive },
+  { "recursive", 0, NULL, MU_OPTION_DEFAULT,
+    N_("recursively delete all subfolders"),
+    mu_c_bool, &recursive },
+  MU_OPTION_END
+};
+
 static char *
 current_folder_path (void)
 {
@@ -185,9 +153,7 @@ main (int argc, char **argv)
   /* Native Language Support */
   MU_APP_INIT_NLS ();
 
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, NULL);
+  mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
 
   cur_folder_path = current_folder_path ();
 
diff --git a/mh/rmm.c b/mh/rmm.c
index 40ee6cf..7b0de27 100644
--- a/mh/rmm.c
+++ b/mh/rmm.c
@@ -19,37 +19,9 @@
 
 #include <mh.h>
 
-static char doc[] = N_("GNU MH rmm")"\v"
-N_("Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH rmm");
 static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
 
-/* GNU options */
-static struct argp_option options[] = {
-  {"folder",  ARG_FOLDER, N_("FOLDER"), 0,
-   N_("specify folder to operate upon")},
-  { 0 }
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { NULL }
-};
-
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
-{
-  switch (key)
-    {
-    case ARG_FOLDER: 
-      mh_set_current_folder (arg);
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
 static int
 rmm (size_t num, mu_message_t msg, void *data)
 {
@@ -79,7 +51,6 @@ rmseq (const char *name, const char *value, void *data)
 int
 main (int argc, char **argv)
 {
-  int index = 0;
   mu_mailbox_t mbox;
   mu_msgset_t msgset;
   int status;
@@ -88,13 +59,12 @@ main (int argc, char **argv)
   /* Native Language Support */
   MU_APP_INIT_NLS ();
 
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
+  mh_getopt (&argc, &argv, NULL, MH_GETOPT_DEFAULT_FOLDER,
+            args_doc, prog_doc, NULL);
 
   mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
 
-  mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
+  mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
 
   status = mu_msgset_foreach_message (msgset, rmm, NULL);
   
diff --git a/mh/scan.c b/mh/scan.c
index a938aa0..3a197c7 100644
--- a/mh/scan.c
+++ b/mh/scan.c
@@ -26,7 +26,7 @@
 #include <time.h>
 #include <mailutils/observer.h>
 
-static char progdoc[] = N_("GNU MH scan");
+static char prog_doc[] = N_("GNU MH scan");
 static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
 
 static int clear;
@@ -107,7 +107,7 @@ main (int argc, char **argv)
   MU_APP_INIT_NLS ();
 
   mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
-            args_doc, progdoc, NULL);
+            args_doc, prog_doc, NULL);
 
   if (mh_format_parse (format_str, &format))
     {
diff --git a/mh/send.c b/mh/send.c
index 1ecda9f..cb9c2b8 100644
--- a/mh/send.c
+++ b/mh/send.c
@@ -23,91 +23,13 @@
 #include <stdarg.h>
 #include <pwd.h>
 
-static char doc[] = N_("GNU MH send")"\v"
-N_("Options marked with `*' are not yet implemented.\n\
-Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH send");
 static char args_doc[] = N_("FILE [FILE...]");
 
-/* GNU options */
-static struct argp_option options[] = {
-  {"alias",         ARG_ALIAS,         N_("FILE"), 0,
-   N_("specify additional alias file") },
-  {"draft",         ARG_DRAFT,         NULL, 0,
-   N_("use prepared draft") },
-  {"draftfolder",   ARG_DRAFTFOLDER,   N_("FOLDER"), 0,
-   N_("specify the folder for message drafts") },
-  {"draftmessage",  ARG_DRAFTMESSAGE,  N_("MSG"), 0,
-   N_("use MSG from the draftfolder as a draft") },
-  {"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0,
-   N_("undo the effect of the last --draftfolder option") },
-  {"filter",        ARG_FILTER,        N_("FILE"), 0,
-  N_("* use filter FILE to preprocess the body of the message") },
-  {"nofilter",      ARG_NOFILTER,      NULL, 0,
-   N_("* undo the effect of the last --filter option") },
-  {"format",        ARG_FORMAT,        N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("* reformat To: and Cc: addresses") },
-  {"noformat",      ARG_NOFORMAT,      NULL, OPTION_HIDDEN, "" },
-  {"forward",       ARG_FORWARD,       N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("* in case of failure forward the draft along with the failure notice to 
the sender") },
-  {"noforward",     ARG_NOFORWARD,     NULL, OPTION_HIDDEN, "" },
-  {"mime",          ARG_MIME,          N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("* use MIME encapsulation") },
-  {"nomime",        ARG_NOMIME,        NULL, OPTION_HIDDEN, "" },
-  {"msgid",         ARG_MSGID,         N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("add Message-ID: field") },
-  {"nomsgid",       ARG_NOMSGID,       NULL, OPTION_HIDDEN, ""},
-  {"push",          ARG_PUSH,          N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("run in the background") },
-  {"nopush",        ARG_NOPUSH,        NULL, OPTION_HIDDEN, "" },
-  {"preserve",      ARG_PRESERVE,      N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("keep draft files") },
-  {"keep",          0, NULL, OPTION_ALIAS, NULL},
-  {"split",         ARG_SPLIT,         N_("SECONDS"), 0,
-   N_("split the draft into several partial messages and send them with 
SECONDS interval") },
-  {"chunksize",     ARG_CHUNKSIZE,     N_("NUMBER"), 0,
-   N_("set the size of chunk for --split (in bytes)") },
-  {"verbose",       ARG_VERBOSE,       N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("print the transcript of interactions with the transport system") },
-  {"noverbose",     ARG_NOVERBOSE,     NULL, OPTION_HIDDEN, "" },
-  {"watch",         ARG_WATCH,         N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("monitor the delivery of mail") },
-  {"nowatch",       ARG_NOWATCH,       NULL, OPTION_HIDDEN, "" },
-  {"width",         ARG_WIDTH,         N_("NUMBER"), 0,
-   N_("* make header fields no longer than NUMBER columns") },
-  { 0 }
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "alias",         MH_OPT_ARG, "aliasfile" },
-  { "draft" },
-  { "draftfolder",   MH_OPT_ARG, "folder" },
-  { "draftmessage",  MH_OPT_ARG, "message" },
-  { "nodraftfolder" },
-  { "filter",        MH_OPT_ARG, "filterfile" },
-  { "nofilter" },
-  { "format",        MH_OPT_BOOL },
-  { "forward",       MH_OPT_BOOL },
-  { "mime",          MH_OPT_BOOL },
-  { "msgid",         MH_OPT_BOOL },
-  { "push",          MH_OPT_BOOL },
-  { "preserve",      MH_OPT_BOOL },
-  { "keep",          MH_OPT_BOOL },
-  { "split",         MH_OPT_ARG, "seconds" },
-  { "verbose",       MH_OPT_BOOL },
-  { "watch",         MH_OPT_BOOL },
-  { "width" },
-  { NULL }
-};
-
 static const char *draftfolder;  /* Use this draft folder */
 static int use_draftfolder = 1;
 static int use_draft;
 
-static int reformat_recipients;  /* --format option */
-static int forward_notice;       /* Forward the failure notice to the sender,
-                                   --forward flag */
-static int mime_encaps;          /* Use MIME encapsulation */
 static int append_msgid;         /* Append Message-ID: header */
 static int background;           /* Operate in the background */
 
@@ -117,7 +39,6 @@ static unsigned long split_interval; /* Interval in seconds 
between sending two
 static size_t split_size = 76*632;   /* Size of split parts */
 static int verbose;              /* Produce verbose diagnostics */
 static int watch;                /* Watch the delivery process */
-static unsigned width = 76;      /* Maximum width of header fields */
 
 static int keep_files;           /* Keep draft files */
 
@@ -128,147 +49,116 @@ static int keep_files;           /* Keep draft files */
     watch_printf c;\
 } while (0)
 
-static int add_file (char *name);
+static int add_file (char const *name);
 static void mesg_list_fixup (void);
+
+static void
+add_alias (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  mh_alias_read (arg, 1);
+}
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
+static void
+set_draftfolder (struct mu_parseopt *po, struct mu_option *opt,
+                char const *arg)
 {
-  char *p;
-  
-  switch (key)
-    {
-    case ARG_ALIAS:
-      mh_alias_read (arg, 1);
-      break;
+  draftfolder = mu_strdup (arg);
+  use_draftfolder = 1;
+}
 
-    case ARG_CHUNKSIZE:
-      split_size = strtoul (arg, &p, 10);
-      if (*p)
-       {
-         argp_error (state, "%s: %s", arg, _("invalid number"));
-         exit (1);
-       }
-      break;
-       
-    case ARG_DRAFT:
-      use_draft = 1;
-      break;
-       
-    case ARG_DRAFTFOLDER:
-      draftfolder = arg;
-      use_draftfolder = 1;
-      break;
-      
-    case ARG_NODRAFTFOLDER:
-      draftfolder = NULL;
-      use_draftfolder = 0;
-      break;
-      
-    case ARG_DRAFTMESSAGE:
-      add_file (arg);
-      break;
-      
-    case ARG_FILTER:
-      mh_opt_notimpl ("-filter");
-      break;
+static void
+add_draftmessage (struct mu_parseopt *po, struct mu_option *opt,
+                 char const *arg)
+{
+  add_file (arg);
+}
 
-    case ARG_NOFILTER:
-      mh_opt_notimpl ("-nofilter");
-      break;
- 
-    case ARG_FORMAT:
-      mh_opt_notimpl_warning ("-format"); 
-      reformat_recipients = is_true (arg);
-      break;
-      
-    case ARG_NOFORMAT:
-      mh_opt_notimpl_warning ("-noformat"); 
-      reformat_recipients = 0;
-      break;
-      
-    case ARG_FORWARD:
-      mh_opt_notimpl_warning ("-forward");
-      forward_notice = is_true (arg);
-      break;
-      
-    case ARG_NOFORWARD:
-      mh_opt_notimpl_warning ("-noforward");
-      forward_notice = 0;
-      break;
-      
-    case ARG_MIME:
-      mh_opt_notimpl_warning ("-mime");
-      mime_encaps = is_true (arg);
-      break;
-      
-    case ARG_NOMIME:
-      mh_opt_notimpl_warning ("-nomime");
-      mime_encaps = 0;
-      break;
-      
-    case ARG_MSGID:
-      append_msgid = is_true (arg);
-      break;
-      
-    case ARG_NOMSGID:
-      append_msgid = 0;
-      break;
+static void
+set_split_opt (struct mu_parseopt *po, struct mu_option *opt,
+              char const *arg)
+{
+  char *errmsg;
+  int rc = mu_str_to_c (arg, opt->opt_type, opt->opt_ptr, &errmsg);
+  if (rc)
+    {
+      char const *errtext;
+      if (errmsg)
+       errtext = errmsg;
+      else
+       errtext = mu_strerror (rc);
 
-    case ARG_PRESERVE:
-      keep_files = is_true (arg);
-      break;
-      
-    case ARG_PUSH:
-      background = is_true (arg);
-      break;
-      
-    case ARG_NOPUSH:
-      background = 0;
-      break;
-      
-    case ARG_SPLIT:
-      split_message = 1;
-      split_interval = strtoul (arg, &p, 10);
-      if (*p)
-       {
-         argp_error (state, "%s: %s", arg, _("invalid number"));
-         exit (1);
-       }
-      break;
-      
-    case ARG_VERBOSE:
-      verbose = is_true (arg);
-      break;
-      
-    case ARG_NOVERBOSE:
-      verbose = 0;
-      break;
-      
-    case ARG_WATCH:
-      watch = is_true (arg);
-      break;
-      
-    case ARG_NOWATCH:
-      watch = 0;
-      break;
-      
-    case ARG_WIDTH:
-      mh_opt_notimpl_warning ("-width");
-      width = strtoul (arg, &p, 10);
-      if (*p)
-       {
-         argp_error (state, _("invalid number"));
-         exit (1);
-       }
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
+      mu_parseopt_error (po, "%s%s: %s", po->po_long_opt_start,
+                        opt->opt_long, errtext);
+      free (errmsg);
+
+      if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT))
+       exit (po->po_exit_error);
     }
-  return 0;
+  split_message = 1;
 }
 
+static struct mu_option options[] = {
+  { "alias",        0,    N_("FILE"), MU_OPTION_DEFAULT,
+    N_("specify additional alias file"),
+    mu_c_string, NULL, add_alias },
+  { "draft",        0,    NULL, MU_OPTION_DEFAULT,
+    N_("use prepared draft"),
+    mu_c_bool, &use_draft },
+  { "draftfolder",  0,   N_("FOLDER"), MU_OPTION_DEFAULT,
+    N_("specify the folder for message drafts"),
+    mu_c_string, NULL, set_draftfolder },
+  { "draftmessage", 0,   N_("MSG"), MU_OPTION_DEFAULT,
+    N_("use MSG from the draftfolder as a draft"),
+    mu_c_string, NULL, add_draftmessage },
+  { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
+    N_("undo the effect of the last --draftfolder option"),
+    mu_c_int, &use_draftfolder, NULL, "1" },
+  { "filter",        0, N_("FILE"), MU_OPTION_HIDDEN,
+    N_("use filter FILE to preprocess the body of the message"),
+    mu_c_string, NULL, mh_opt_notimpl },
+  { "nofilter",      0, NULL, MU_OPTION_HIDDEN,
+    N_("undo the effect of the last --filter option"),
+    mu_c_string, NULL, mh_opt_notimpl },
+  { "format",        0, NULL, MU_OPTION_HIDDEN,
+    N_("reformat To: and Cc: addresses"),
+    mu_c_string, NULL, mh_opt_notimpl_warning },
+  { "noformat",      0, NULL, MU_OPTION_HIDDEN },
+  { "forward",       0, NULL, MU_OPTION_HIDDEN,
+    N_("in case of failure forward the draft along with the failure notice to 
the sender"),
+    mu_c_string, NULL, mh_opt_notimpl_warning },
+  { "noforward",     0, NULL, MU_OPTION_HIDDEN, "" },
+  { "mime",          0, NULL, MU_OPTION_HIDDEN,
+    N_("use MIME encapsulation"),
+    mu_c_bool, NULL, mh_opt_notimpl_warning },
+  { "msgid",         0, NULL, MU_OPTION_DEFAULT,
+    N_("add Message-ID: field"),
+    mu_c_bool, &append_msgid },
+  { "push",          0, NULL, MU_OPTION_DEFAULT,
+    N_("run in the background"),
+    mu_c_bool, &background },
+  { "preserve",      0, NULL, MU_OPTION_DEFAULT,
+    N_("keep draft files"),
+    mu_c_bool, &keep_files },
+  { "keep",          0, NULL, MU_OPTION_ALIAS },
+  { "split",         0, N_("SECONDS"), MU_OPTION_DEFAULT,
+   N_("split the draft into several partial messages and send them with 
SECONDS interval"),
+    mu_c_ulong, &split_interval, set_split_opt },
+  { "chunksize",     0, N_("NUMBER"), MU_OPTION_DEFAULT,
+    N_("set the size of chunk for --split (in bytes)"),
+    mu_c_size, &split_size },
+  { "verbose",       0, NULL, MU_OPTION_DEFAULT,
+    N_("print the transcript of interactions with the transport system"),
+    mu_c_bool, &verbose },
+  { "watch",         0, NULL, MU_OPTION_DEFAULT,
+    N_("monitor the delivery of mail"),
+    mu_c_bool, &watch },
+  { "width",         0, N_("NUMBER"), MU_OPTION_HIDDEN,
+    N_("make header fields no longer than NUMBER columns"),
+    mu_c_string, NULL, mh_opt_notimpl_warning },
+
+  MU_OPTION_END
+};
+
 static void
 watch_printf (const char *fmt, ...)
 {
@@ -291,7 +181,7 @@ static mu_list_t mesg_list;
 static mu_property_t mts_profile;
 
 int
-add_file (char *name)
+add_file (char const *name)
 {
   struct list_elt *elt;
 
@@ -859,17 +749,12 @@ int
 main (int argc, char **argv)
 {
   mu_mailbox_t mbox = NULL;
-  int index;
   char *p;
   int rc;
   
   MU_APP_INIT_NLS ();
   
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
-  argc -= index;
-  argv += index;
+  mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
 
   mh_read_aliases ();
   /* Process the mtstailor file */
diff --git a/mh/show.c b/mh/show.c
index e2bc1c0..fcd87eb 100644
--- a/mh/show.c
+++ b/mh/show.c
@@ -19,55 +19,9 @@
 
 #include <mh.h>
 
-static char doc[] = N_("GNU MH show")"\v"
-N_("Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH show");
 static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
 
-#define ARG_PASS ARG_MAX
-
-static struct argp_option options[] = {
-  {"draft",         ARG_DRAFT,          NULL, 0,
-   N_("show the draft file") },
-  {"file",          ARG_FILE,     N_("FILE"), 0,
-   N_("show this file") },
-  {"header",        ARG_HEADER,   N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("display a description of the message before the message itself") },
-  {"noheader",      ARG_HEADER,   NULL, OPTION_HIDDEN, "" },
-  {"showproc",      ARG_SHOWPROC, N_("PROGRAM"), 0,
-   N_("use PROGRAM to show messages")},
-  {"noshowproc",    ARG_NOSHOWPROC, NULL, 0,
-   N_("disable the use of the \"showproc:\" profile component") },
-
-  {"form",          ARG_FORM,     N_("FILE"),   0,
-   N_("read format from given file")},
-  {"moreproc",      ARG_MOREPROC, N_("PROG"),   0,
-   N_("use this PROG as pager"), },
-  {"nomoreproc",    ARG_NOMOREPROC,     NULL,         0,
-   N_("disable the use of moreproc") },
-  {"length",        ARG_LENGTH,   N_("NUMBER"), 0,
-   N_("set output screen length")},
-  {"width",         ARG_WIDTH,    N_("NUMBER"), 0,
-   N_("set output width")},
-  
-  {NULL}
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "draft" },
-  { "file", MH_OPT_ARG, "file" },
-  { "header", MH_OPT_BOOL },
-  { "showproc", MH_OPT_ARG, "program" },
-  { "noshowproc" },
-  { "form",       MH_OPT_ARG, "formatfile"},
-  { "width",      MH_OPT_ARG, "number"},
-  { "length",     MH_OPT_ARG, "number"},
-  { "moreproc",   MH_OPT_ARG, "program"},
-  { "nomoreproc" },
-  
-  { NULL }
-};
-
 int use_draft;
 int use_showproc = 1;
 int header_option = 1;
@@ -100,71 +54,75 @@ insarg (char *arg)
       showargv[1] = p;
     }
 }
-
-static const char *
-findopt (int key)
+
+static void
+set_draft (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
-  struct argp_option *p;
-
-  for (p = options; p->name; p++)
-    if (p->key == key)
-      return p->name;
-  abort ();
+  if (use_draft || file)
+    {
+      mu_parseopt_error (po, _("only one file at a time!"));
+      exit (po->po_exit_error);
+    }
+  use_draft = 1;
 }
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
+static void
+set_file (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
-  switch (key)
+  if (use_draft || file)
     {
-    case ARG_FOLDER: 
-      mh_set_current_folder (arg);
-      break;
-
-    case ARG_DRAFT:
-      if (use_draft || file)
-       argp_error (state, _("only one file at a time!"));
-      use_draft = 1;
-      break;
-
-    case ARG_FILE:
-      if (use_draft || file)
-       argp_error (state, _("only one file at a time!"));
-      file = mh_expand_name (NULL, arg, NAME_FILE);
-      break;
-      
-    case ARG_HEADER:
-      header_option = is_true (arg);
-      break;
-
-    case ARG_NOHEADER:
-      header_option = 0;
-      break;
-
-    case ARG_SHOWPROC:
-      showproc = arg;
-      break;
-
-    case ARG_NOSHOWPROC:
-      use_showproc = 0;
-      break;
-      
-    case ARG_NOMOREPROC:
-    case ARG_FORM:
-    case ARG_MOREPROC:
-    case ARG_LENGTH:
-    case ARG_WIDTH:
-      addarg (findopt (key));
-      if (arg)
-       addarg (arg);
-      break;
-
-    default:
-      return ARGP_ERR_UNKNOWN;
+      mu_parseopt_error (po, _("only one file at a time!"));
+      exit (po->po_exit_error);
     }
-  return 0;
+  file = mh_expand_name (NULL, arg, NAME_FILE);
+}
+
+static void
+add_show_arg (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  char *name = mu_alloc (strlen (opt->opt_long) + 2);
+  name[0] = '-';
+  strcpy (name + 1, opt->opt_long);
+  addarg (name);
+  if (arg)
+    addarg (arg);
 }
 
+static struct mu_option options[] = {
+  { "draft",        0,     NULL, MU_OPTION_DEFAULT,
+    N_("show the draft file"),
+    mu_c_string, NULL, set_draft },
+  { "file",         0,     N_("FILE"), MU_OPTION_DEFAULT,
+    N_("show this file"),
+    mu_c_string, NULL, set_file },
+  { "header",       0,     NULL, MU_OPTION_DEFAULT,
+    N_("display a description of the message before the message itself"),
+    mu_c_bool, &header_option },
+  { "showproc",     0,     N_("PROGRAM"), MU_OPTION_DEFAULT,
+    N_("use PROGRAM to show messages"),
+    mu_c_string, &showproc },
+  { "noshowproc",   0,  NULL, MU_OPTION_DEFAULT,
+    N_("disable the use of the \"showproc:\" profile component"),
+    mu_c_int, &use_showproc, NULL, "0" },
+  { "form",         0,  N_("FILE"),  MU_OPTION_DEFAULT,
+    N_("read format from given file"),
+    mu_c_string, NULL, add_show_arg },
+  { "moreproc",     0, N_("PROG"),   MU_OPTION_DEFAULT,
+    N_("use this PROG as pager"),
+    mu_c_string, NULL, add_show_arg },
+  { "nomoreproc",   0, NULL,         MU_OPTION_DEFAULT,
+    N_("disable the use of moreproc"),
+    mu_c_string, NULL, add_show_arg },
+  { "length",       0, N_("NUMBER"), MU_OPTION_DEFAULT,
+    N_("set output screen length"),
+    mu_c_string, NULL, add_show_arg },
+  { "width",        0, N_("NUMBER"), MU_OPTION_DEFAULT,
+    N_("set output width"),
+    mu_c_string, NULL, add_show_arg },
+  
+  MU_OPTION_END
+};
+
 static int
 resolve_mime (size_t num, mu_message_t msg, void *data)
 {
@@ -222,7 +180,6 @@ checkfile (char *file)
 int
 main (int argc, char **argv)
 {
-  int index = 0;
   mu_mailbox_t mbox;
   mu_msgset_t msgset;
   const char *p;
@@ -233,15 +190,13 @@ main (int argc, char **argv)
   showargmax = 2;
   showargc = 1;
   showargv = mu_calloc (showargmax, sizeof showargv[0]);
+
+  mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
+            args_doc, prog_doc, NULL);
+
   
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
   mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
 
-  argc -= index;
-  argv += index;
-  
   if (use_draft || file)
     {
       if (argc)
diff --git a/mh/sortm.c b/mh/sortm.c
index f2e1290..bb991cf 100644
--- a/mh/sortm.c
+++ b/mh/sortm.c
@@ -22,72 +22,10 @@
 #include <unistd.h>
 #include <signal.h>
 
-static char doc[] = N_("GNU MH sortm")"\v"
+static char prog_doc[] = N_("GNU MH sortm")"\v"
 N_("Use -help to obtain the list of traditional MH options.");
 static char args_doc[] = N_("[MSGLIST]");
 
-#define ARG_QUICKSORT 1024
-#define ARG_SHELL     1025
-
-/* GNU options */
-static struct argp_option options[] = {
-  {"folder",        ARG_FOLDER,        N_("FOLDER"), 0,
-   N_("specify folder to operate upon")},
-
-  {N_("Setting sort keys:"), 0,  NULL, OPTION_DOC,  NULL, 0},
-  {"datefield",     ARG_DATEFIELD,     N_("STRING"), 0,
-   N_("sort on the date field (default `Date:')"), 10},
-  {"nodatefield",   ARG_NODATEFIELD,   NULL,       0,
-   N_("undo the effect of the last --datefield option"), 10},
-  {"limit",         ARG_LIMIT,         N_("DAYS"), 0,
-   N_("consider two datefields equal if their difference lies within the given 
nuber of DAYS."), 11},
-  {"nolimit",       ARG_NOLIMIT,       NULL,       0,
-   N_("undo the effect of the last --limit option"), 11},
-  {"textfield",     ARG_TEXTFIELD,     N_("STRING"), 0,
-   N_("sort on the text field"), 15},
-  {"notextfield",   ARG_NOTEXTFIELD,   NULL,       0,
-   N_("undo the effect of the last --textfield option"), 15},
-  {"numfield",      ARG_NUMFIELD,      N_("STRING"), 0,
-   N_("sort on the numeric field"), 16},
-  
-  {N_("Actions:"), 0,  NULL, OPTION_DOC,  NULL, 16},
-  {"reorder", ARG_REORDER,    0, 0,
-   N_("reorder the messages (default)"), 20 },
-  {"dry-run", ARG_DRY_RUN,    0, 0,
-   N_("do not do anything, only show what would have been done"), 20 },
-  {"list",    ARG_LIST,   0, 0,
-   N_("list the sorted messages"), 20 },
-  {"form",    ARG_FORM, N_("FILE"),   0,
-   N_("read format from given file"), 23},
-  {"format",  ARG_FORMAT, N_("FORMAT"), 0,
-   N_("use this format string"), 23},
-
-  {"verbose",       ARG_VERBOSE,       N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("verbosely list executed actions"), 30 },
-  {"noverbose",     ARG_NOVERBOSE,     NULL, OPTION_HIDDEN, "" },
-
-  {N_("Select sort algorithm:"), 0,  NULL, OPTION_DOC,  NULL, 30},
-
-  {"shell",     ARG_SHELL,      0, 0,
-   N_("use shell algorithm"), 40 },
-  {"quicksort", ARG_QUICKSORT,  0, 0,
-   N_("use quicksort algorithm (default)"), 40 },
-
-  { NULL },
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "datefield",     MH_OPT_ARG, "field" },
-  { "nodatefield" },
-  { "textfield",     MH_OPT_ARG, "field" },
-  { "notextfield" },
-  { "limit",         MH_OPT_ARG, "days" },
-  { "nolimit" },
-  { "verbose",       MH_OPT_BOOL },
-  { NULL },
-};
-
 static int limit;
 static int verbose;
 static mu_mailbox_t mbox;
@@ -98,115 +36,175 @@ static size_t msgcount;
 
 static size_t current_num;
 
-#define ACTION_REORDER   0
-#define ACTION_DRY_RUN   1
-#define ACTION_LIST      2  
-
-static int algorithm = ARG_QUICKSORT;
+enum
+  {
+    ACTION_REORDER,
+    ACTION_DRY_RUN,
+    ACTION_LIST
+  };
+
+enum
+  {
+    algo_quicksort,
+    algo_shell
+  };
+static int algorithm = algo_quicksort;
 static int action = ACTION_REORDER;
 static char *format_str = mh_list_format;
 static mh_format_t format;
 
 typedef int (*compfun) (void *, void *);
-static void addop (char *field, compfun comp);
+static void addop (char const *field, compfun comp);
 static void remop (compfun comp);
 static int comp_text (void *a, void *b);
 static int comp_date (void *a, void *b);
 static int comp_number (void *a, void *b);
+
+static void
+add_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  addop (arg, comp_date);
+}
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
+static void
+add_numfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
-  switch (key)
-    {
-    case ARG_FOLDER:
-      mh_set_current_folder (arg);
-      break;
-      
-    case ARG_DATEFIELD:
-      addop (arg, comp_date);
-      break;
-      
-    case ARG_NUMFIELD:
-      addop (arg, comp_number);
-      break;
+  addop (arg, comp_number);
+}
 
-    case ARG_NODATEFIELD:
-      remop (comp_date);
-      break;
-      
-    case ARG_TEXTFIELD:
-      addop (arg, comp_text);
-      break;
-      
-    case ARG_NOTEXTFIELD:
-      remop (comp_text);
-      break;
-      
-    case ARG_LIMIT:
-      limit = strtoul (arg, NULL, 0);
-      break;
-      
-    case ARG_NOLIMIT:
-      limit = -1;
-      break;
-      
-    case ARG_VERBOSE:
-      if (!arg || mu_isalpha (arg[0]))
-       verbose = is_true (arg);
-      else
-       verbose = arg[0] - '0';
-      break;
-      
-    case ARG_NOVERBOSE:
-      verbose = 0;
-      break;
-      
-    case ARG_FORM:
-      mh_read_formfile (arg, &format_str);
-      break;
-      
-    case ARG_FORMAT:
-      format_str = arg;
-      break;
+static void
+add_textfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  addop (arg, comp_text);
+}
 
-    case ARG_REORDER:
-      action = ACTION_REORDER;
-      break;
-      
-    case ARG_LIST:
-      action = ACTION_LIST;
-      break;
+static void
+rem_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  remop (comp_date);
+}
 
-    case ARG_DRY_RUN:
-      action = ACTION_DRY_RUN;
-      if (!verbose)
-       verbose = 1;
-      break;
+static void
+rem_numfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  remop (comp_number);
+}
 
-    case ARG_SHELL:
-    case ARG_QUICKSORT:
-      algorithm = key;
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
+static void
+rem_textfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
+{
+  remop (comp_text);
+}
+
+static void
+set_action_reorder (struct mu_parseopt *po, struct mu_option *opt,
+                   char const *arg)
+{
+  action = ACTION_REORDER;
+}
+
+static void
+set_action_list (struct mu_parseopt *po, struct mu_option *opt,
+                   char const *arg)
+{
+  action = ACTION_LIST;
 }
 
+static void
+set_action_dry_run (struct mu_parseopt *po, struct mu_option *opt,
+                   char const *arg)
+{
+  action = ACTION_DRY_RUN;
+  if (!verbose)
+    verbose = 1;
+}
+
+static void
+set_algo_shell (struct mu_parseopt *po, struct mu_option *opt,
+               char const *arg)
+{
+  algorithm = algo_shell;
+}
+
+static void
+set_algo_quicksort (struct mu_parseopt *po, struct mu_option *opt,
+                   char const *arg)
+{
+  algorithm = algo_quicksort;
+}
+
+static struct mu_option options[] = {
+  MU_OPTION_GROUP (N_("Setting sort keys:")),
+  { "datefield",     0, N_("STRING"), MU_OPTION_DEFAULT,
+    N_("sort on the date field (default `Date:')"),
+    mu_c_string, NULL, add_datefield },
+  { "nodatefield",   0, NULL,       MU_OPTION_DEFAULT,
+    N_("don't sort on the date field"),
+    mu_c_string, NULL, rem_datefield },
+  { "limit",         0, N_("DAYS"), MU_OPTION_DEFAULT,
+    N_("consider two datefields equal if their difference lies within the 
given nuber of DAYS."),
+    mu_c_int, &limit },
+  { "nolimit",       0,       NULL,       MU_OPTION_DEFAULT,
+    N_("undo the effect of the last -limit option"),
+    mu_c_int, &limit, NULL, "-1" },
+  { "textfield",     0,       N_("STRING"), MU_OPTION_DEFAULT,
+    N_("sort on the text field"),
+    mu_c_string, NULL, add_textfield },
+  { "notextfield",   0,       NULL,       MU_OPTION_DEFAULT, 
+    N_("don't sort on the text field"),
+    mu_c_string, NULL, rem_textfield },
+  { "numfield",      0,       N_("STRING"), MU_OPTION_DEFAULT,
+    N_("sort on the numeric field"),
+    mu_c_string, NULL, add_numfield },
+  { "nonumfield",    0,       NULL,       MU_OPTION_DEFAULT,
+    N_("don't sort on the numeric field"),
+    mu_c_string, NULL, rem_numfield },
+  
+  MU_OPTION_GROUP (N_("Actions:")),
+  { "reorder", 0,    NULL, MU_OPTION_DEFAULT,
+    N_("reorder the messages (default)"),
+    mu_c_string, NULL, set_action_reorder },
+  { "dry-run", 0,    NULL, MU_OPTION_DEFAULT,
+   N_("do not do anything, only show what would have been done"),
+    mu_c_string, NULL, set_action_dry_run },
+  { "list",    0,    NULL, MU_OPTION_DEFAULT,
+    N_("list the sorted messages"), 
+    mu_c_string, NULL, set_action_list },
+  
+  { "form",    0, N_("FILE"),   MU_OPTION_DEFAULT,
+    N_("read format from given file"),
+    mu_c_string, &format_str, mh_opt_read_formfile },
+  { "format",  0, N_("FORMAT"), MU_OPTION_DEFAULT,
+    N_("use this format string"),
+    mu_c_string, &format_str },
+
+  { "verbose",  0, NULL,   MU_OPTION_DEFAULT,
+    N_("verbosely list executed actions"),
+    mu_c_bool, &verbose },
+
+  MU_OPTION_GROUP (N_("Select sort algorithm:")),
+  { "shell",    0, NULL,   MU_OPTION_DEFAULT,
+    N_("use shell algorithm"),
+    mu_c_string, NULL, set_algo_shell },
+  
+  { "quicksort", 0, NULL,   MU_OPTION_DEFAULT,
+    N_("use quicksort algorithm (default)"),
+    mu_c_string, NULL, set_algo_quicksort },
+
+  MU_OPTION_END
+};
 
 /* *********************** Comparison functions **************************** */
 struct comp_op
 {
-  char *field;
+  char const *field;
   compfun comp;
 };
 
 static mu_list_t oplist;
 
 static void
-addop (char *field, compfun comp)
+addop (char const *field, compfun comp)
 {
   struct comp_op *op = mu_alloc (sizeof (*op));
   
@@ -497,11 +495,11 @@ sort ()
 
   switch (algorithm)
     {
-    case ARG_QUICKSORT:
+    case algo_quicksort:
       qsort (msgarr, msgcount, sizeof (msgarr[0]), comp);
       break;
 
-    case ARG_SHELL:
+    case algo_shell:
       shell_sort ();
       break;
     }
@@ -599,19 +597,17 @@ fill_msgarr (mu_msgset_t msgset)
 }
 
 
-/* Main */
-
 int
 main (int argc, char **argv)
 {
-  int index;
   mu_url_t url;
   mu_msgset_t msgset;
   
   MU_APP_INIT_NLS ();
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option,
-                args_doc, doc, opt_handler, NULL, &index);
+
+  mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
+            args_doc, prog_doc, NULL);
+  
   if (!oplist)
     addop ("date", comp_date);
 
@@ -627,9 +623,6 @@ main (int argc, char **argv)
   if (memcmp (mbox_path, "mh:", 3) == 0)
     mbox_path += 3;
   
-  argc -= index;
-  argv += index;
-
   mh_mailbox_get_cur (mbox, &current_num);
 
   mh_msgset_parse (&msgset, mbox, argc, argv, "all");
diff --git a/mh/tests/refile.at b/mh/tests/refile.at
index 46aea36..caec370 100644
--- a/mh/tests/refile.at
+++ b/mh/tests/refile.at
@@ -53,11 +53,11 @@ Mail/inbox/5
 Mail/inbox/6
 ])
 
-MH_CHECK([refile --copy],[refile02 refile--copy],[
+MH_CHECK([refile -copy],[refile02 refile-copy],[
 MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
 MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty,[Mail/teaparty])
 echo 'Current-Folder: teaparty' > Mail/context
-refile --copy 3 4 +inbox || exit $?
+refile -copy 3 4 +inbox || exit $?
 find Mail/inbox -name '[[0-9]]' | sort
 cmp Mail/inbox/6 Mail/teaparty/3 >/dev/null || echo "Message 3 differs"
 cmp Mail/inbox/7 Mail/teaparty/4 >/dev/null || echo "Message 4 differs"
diff --git a/mh/whatnow.c b/mh/whatnow.c
index 0ca7add..9e0d38e 100644
--- a/mh/whatnow.c
+++ b/mh/whatnow.c
@@ -19,88 +19,45 @@
 
 #include <mh.h>
 
-static char doc[] = "GNU MH whatnow";
+static char prog_doc[] = "GNU MH whatnow";
 static char args_doc[] = N_("[FILE]");
 
-/* GNU options */
-static struct argp_option options[] = {
-  {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
-   N_("specify the folder for message drafts")},
-  {"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0,
-   N_("undo the effect of the last --draftfolder option")},
-  {"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0,
-   N_("invoke the draftmessage facility")},
-  {"editor",  ARG_EDITOR, N_("PROG"), 0, N_("set the editor program to use")},
-  {"noedit", ARG_NOEDIT, 0, 0, N_("suppress the initial edit")},
-  {"prompt", ARG_PROMPT, N_("STRING"), 0, N_("set the prompt")},
-
-  { NULL }
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "draftfolder",  MH_OPT_ARG, "folder" },
-  { "nodraftfolder" },
-  { "draftmessage" },
-  { "editor",       MH_OPT_ARG, "program" },
-  { "noedit" },
-  { "prompt" },
-  { NULL }
-};
-
 struct mh_whatnow_env wh_env = { 0 };
 static int initial_edit = 1;
 static char *draftmessage = "cur";
 static const char *draftfolder = NULL;
 
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
-{
-  switch (key)
-    {
-    case ARG_DRAFTFOLDER:
-      draftfolder = arg;
-      break;
-      
-    case ARG_EDITOR:
-      wh_env.editor = arg;
-      break;
-      
-    case ARG_NODRAFTFOLDER:
-      draftfolder = NULL;
-      break;
-
-    case ARG_NOEDIT:
-      initial_edit = 0;
-      break;
-
-    case ARG_DRAFTMESSAGE:
-      draftmessage = arg;
-      break;
-
-    case ARG_PROMPT:
-      wh_env.prompt = arg;
-      break;
-      
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
+static struct mu_option options[] = {
+  { "draftfolder",   0,      N_("FOLDER"), MU_OPTION_DEFAULT,
+    N_("specify the folder for message drafts"),
+    mu_c_string, &draftfolder },
+  { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
+    N_("undo the effect of the last -draftfolder option"),
+    mu_c_string, &draftfolder, mh_opt_clear_string },
+  { "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT,
+    N_("invoke the draftmessage facility"),
+    mu_c_string, &draftmessage },
+  { "editor",        0, N_("PROG"), MU_OPTION_DEFAULT,
+    N_("set the editor program to use"),
+    mu_c_string, &wh_env.editor },
+  { "noedit",        0, NULL, MU_OPTION_DEFAULT,
+    N_("suppress the initial edit"),
+    mu_c_int, &initial_edit, NULL, "0" },
+  { "prompt", 0, N_("STRING"), MU_OPTION_DEFAULT,
+    N_("set the prompt"),
+    mu_c_string, &wh_env.prompt },
+  MU_OPTION_END
+};
+
 int
 main (int argc, char **argv)
 {
-  int index;
-  
   MU_APP_INIT_NLS ();
 
-  mh_argp_init ();
   mh_whatnow_env_from_environ (&wh_env);
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
-  argc -= index;
-  argv += index;
+
+  mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
+  
   if (argc)
     wh_env.draftfile = argv[0];
   else if (draftfolder)
diff --git a/mh/whom.c b/mh/whom.c
index 792a032..f21eee4 100644
--- a/mh/whom.c
+++ b/mh/whom.c
@@ -17,99 +17,58 @@
 
 #include <mh.h>
 
-static char doc[] = N_("GNU MH whom")"\v"
-N_("Use -help to obtain the list of traditional MH options.");
+static char prog_doc[] = N_("GNU MH whom");
 static char args_doc[] = "[FILE]";
 
-/* GNU options */
-static struct argp_option options[] = {
-  {"alias",         ARG_ALIAS,         N_("FILE"), 0,
-   N_("specify additional alias file") },
-  {"draft",         ARG_DRAFT,         NULL, 0,
-   N_("use prepared draft") },
-  {"draftfolder",   ARG_DRAFTFOLDER,   N_("FOLDER"), 0,
-   N_("specify the folder for message drafts") },
-  {"draftmessage",  ARG_DRAFTMESSAGE,  NULL, 0,
-   N_("treat the arguments as a list of messages from the draftfolder") },
-  {"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0,
-   N_("undo the effect of the last --draftfolder option") },
-  {"check",         ARG_CHECK,         N_("BOOL"), OPTION_ARG_OPTIONAL,
-   N_("check if addresses are deliverable") },
-  {"nocheck",       ARG_NOCHECK,       NULL, OPTION_HIDDEN, "" },
-
-  {NULL}
-};
-
-/* Traditional MH options */
-struct mh_option mh_option[] = {
-  { "alias",         MH_OPT_ARG, "aliasfile" },
-  { "draft" },
-  { "draftfolder",   MH_OPT_ARG, "folder" },
-  { "draftmessage",  MH_OPT_ARG, "message" },
-  { "nodraftfolder" },
-  { "check",         MH_OPT_BOOL },
-  {NULL}
-};
-
 static int check_recipients;
 static int use_draft;            /* Use the prepared draft */
 static const char *draft_folder; /* Use this draft folder */
-
-static error_t
-opt_handler (int key, char *arg, struct argp_state *state)
+
+static void
+add_alias (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
 {
-  switch (key)
-    {
-    case ARG_ALIAS:
-      mh_alias_read (arg, 1);
-      break;
-      
-    case ARG_DRAFT:
-      use_draft = 1;
-      break;
-       
-    case ARG_DRAFTFOLDER:
-      draft_folder = arg;
-      break;
-      
-    case ARG_NODRAFTFOLDER:
-      draft_folder = NULL;
-      break;
-      
-    case ARG_DRAFTMESSAGE:
-      if (!draft_folder)
-       draft_folder = mh_global_profile_get ("Draft-Folder",
-                                             mu_folder_directory ());
-      break;
-
-    case ARG_CHECK:
-      check_recipients = is_true (arg);
-      break;
-
-    case ARG_NOCHECK:
-      check_recipients = 0;
-      break;
+  mh_alias_read (arg, 1);
+}
 
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
+static void
+set_draftmessage (struct mu_parseopt *po, struct mu_option *opt,
+                 char const *arg)
+{
+  if (!draft_folder)
+    draft_folder = mh_global_profile_get ("Draft-Folder",
+                                         mu_folder_directory ());
 }
 
+static struct mu_option options[] = {
+  { "alias",        0,    N_("FILE"), MU_OPTION_DEFAULT,
+    N_("specify additional alias file"),
+    mu_c_string, NULL, add_alias },
+  { "draft",        0,    NULL, MU_OPTION_DEFAULT,
+    N_("use prepared draft"),
+    mu_c_bool, &use_draft },
+  { "draftfolder",   0,      N_("FOLDER"), MU_OPTION_DEFAULT,
+    N_("specify the folder for message drafts"),
+    mu_c_string, &draft_folder },
+  { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
+    N_("undo the effect of the last -draftfolder option"),
+    mu_c_string, &draft_folder, mh_opt_clear_string },
+  { "draftmessage",  0,  NULL, MU_OPTION_DEFAULT,
+    N_("treat the arguments as a list of messages from the draftfolder"),
+    mu_c_string, NULL, set_draftmessage },
+  { "check",         0,  NULL, MU_OPTION_DEFAULT,
+    N_("check if addresses are deliverable"),
+    mu_c_bool, &check_recipients },
+  MU_OPTION_END
+};
+
 int
 main (int argc, char **argv)
 {
-  int index;
   char *name = "draft";
   
   MU_APP_INIT_NLS ();
   
-  mh_argp_init ();
-  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
-                opt_handler, NULL, &index);
-
-  argc -= index;
-  argv += index;
+  mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
 
   if (!use_draft && argc > 0)
     name = argv[0];
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d62e071..e75a7d9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -144,7 +144,6 @@ mh/inc.c
 mh/install-mh.c
 mh/mark.c
 mh/mboxprop.c
-mh/mh_argp.c
 mh/mh_fmtgram.y
 mh/mh_format.c
 mh/mh_getopt.c


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]