Commit e267ac86 e267ac86e2c3a78979fe12bdd16392f30f8d1725 by Sergey Poznyakoff

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.
1 parent f434857b
......@@ -27,9 +27,6 @@ distribution directory.
@subsection Major differences between Mailutils MH and other MH implementations
@enumerate 1
@item 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});
@item 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
@option{--cc} and @option{--nocc} options, unless it has been modified
@option{-cc} 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:
@option{--recurse} and @option{--length}.
@option{-recurse} 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
@item The @option{--moveto} option.
The @option{--moveto} option instructs @command{inc} to move
@item 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 truncate[=@var{bool}]
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.
@item Show mode (@option{--show})
@item 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.
@item Store mode (@option{--store})
@item 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 @option{--@var{component} @var{string}}) is
recognized only if at least one of the following conditions is met:
@itemize @bullet
@item The word @var{component} contains at least one capital letter.
E.g. @option{--User-Agent Mailutils}.
@item The word @var{component} ends with a colon, as in
@option{user-agent: Mailutils}.
@item Standard input is not connected to a terminal.
@end itemize
The GNU syntax for component matching is:
@smallexample
pick --component @var{field} --pattern @var{string}
@end 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
@option{--pattern} or @option{--component} option (or one of its
aliases, like @option{--cc}, @option{--from}, etc.)
@option{--@var{component} @var{pattern}} or equivalent construct (like
@option{-cc}, @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
@option{--link} option. The latter is actually a synonym for @option{--copy},
@option{-link} 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
@option{--numfield} options may be given, thus allowing to build sort
Any number of @option{-datefield}, @option{-textfield} and
@option{-numfield} 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
@item --list
@item -list
List the ordered messages using a format string given by
@option{--form} or @option{--format} option.
@option{-form} or @option{-format} option.
@item --dry-run
@item -dry-run
Do not actually sort messages, rather print what would have been
done. This is useful for debugging purposes.
@end table
......
......@@ -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
......
......@@ -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);
}
}
}
......
......@@ -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)
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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");
......
......@@ -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)
{
......
......@@ -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);
......
......@@ -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;
......
......@@ -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"),
......
......@@ -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++)
{
......
......@@ -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 ();
......
......@@ -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);
......
......@@ -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))
{
......
......@@ -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)
......
......@@ -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");
......
......@@ -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"
......
......@@ -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)
......
......@@ -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];
......
......@@ -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
......