Commit f434857b f434857b8318b05b7036025605ab18cdf3e7c238 by Sergey Poznyakoff

Begin rewriting MH to get rid of argp stuff.

MH utilities will use only single-dash long options.

* include/mailutils/opt.h (mu_option) <opt_default>: New member.
* libmailutils/opt/opt.c (find_long_option): Improve detection
of ambiguous options.
(mu_option_set_value): Use default value (opt_default), if
supplied.
* mh/mh_argp.c: Delete.
* mh/Makefile.am (libmh_a_SOURCES): Remove mh_argp.c
* mh/mh_getopt.c: Rewrite from scratch using mailutils/opt
* mh/mh_getopt.h: Likewise.
* mh/mh.h: Add missing includes
(mh_read_formfile, mh_alias_read): Change signatures.
* mh/mh_alias.l (mh_alias_read): Name is const
* mh/mh_init.c (mh_read_formfile): Name is const.

* mh/ali.c: Convert to mh_getopt.
* mh/anno.c: Likewise.
* mh/burst.c: Likewise.
* mh/comp.c: Likewise.
* mh/fmtcheck.c: Likewise.
* mh/folder.c: Likewise.
* mh/forw.c: Likewise.
* mh/inc.c: Likewise.
* mh/install-mh.c: Likewise.
* mh/mark.c: Likewise.
* mh/mhl.c: Likewise.
* mh/scan.c: Likewise.

* mh/tests/burst.at: Don't use double-dash options
* mh/tests/folder.at: Likewise.
1 parent 53eb6813
......@@ -47,6 +47,7 @@ struct mu_option
void *opt_ptr; /* Data pointer */
void (*opt_set) (struct mu_parseopt *, struct mu_option *, char const *);
/* Function to set the option */
char const *opt_default;/* Default value */
};
#define MU_OPTION_GROUP(text) { NULL, 0, NULL, 0, text }
......
......@@ -189,6 +189,31 @@ find_short_option (struct mu_parseopt *po, int chr)
return NULL;
}
enum neg_match
{
neg_nomatch,
neg_match_inexact,
neg_match_exact
};
static enum neg_match
negmatch (struct mu_parseopt *po, size_t i, char const *optstr, size_t optlen)
{
if (mu_option_possible_negation (po, po->po_optv[i]))
{
size_t neglen = strlen (po->po_negation);
size_t len = strlen (po->po_optv[i]->opt_long);
if (optlen <= neglen + len
&& memcmp (optstr, po->po_negation, neglen) == 0
&& memcmp (optstr + neglen, po->po_optv[i]->opt_long,
optlen - neglen) == 0)
{
return (optlen == neglen + len) ? neg_match_exact : neg_match_inexact;
}
}
return neg_nomatch;
}
/* Find a descriptor of long option OPTSTR. If it has argument, return
it in *ARGPTR. */
struct mu_option *
......@@ -200,14 +225,11 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
size_t i;
size_t optlen; /* Length of the option in optstr */
int found = 0; /* 1 if the match was found, 2 if option is ambiguous */
int neglen; /* Length of the negation prefix, if any */
int neg = 0; /* 1 if a boolean option is negated */
enum neg_match neg; /* 1 if a boolean option is negated */
struct mu_option *ret_opt = NULL;
struct mu_option *used_opt;
optlen = strcspn (optstr, "=");
if (po->po_negation)
neglen = strlen (po->po_negation);
for (i = 0; i < po->po_optc; i++)
{
......@@ -215,14 +237,10 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
{
size_t len = strlen (po->po_optv[i]->opt_long);
struct mu_option *opt = option_unalias (po, i);
neg = neg_nomatch;
if ((optlen <= len
&& memcmp (po->po_optv[i]->opt_long, optstr, optlen) == 0)
|| (neg = (mu_option_possible_negation (po, opt)
&& optlen <= neglen + len
&& memcmp (optstr, po->po_negation, neglen) == 0
&& memcmp (optstr + neglen, po->po_optv[i]->opt_long,
optlen - neglen) == 0)))
|| (neg = negmatch (po, i, optstr, optlen)))
{
switch (found)
{
......@@ -230,7 +248,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
used_opt = po->po_optv[i];
ret_opt = opt;
found++;
if (optlen == len || (neg && optlen == neglen + len))
if (optlen == len || neg == neg_match_exact)
i = po->po_optc - 1; /* exact match: break the loop */
break;
......@@ -247,6 +265,11 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
po->po_long_opt_start,
neg ? po->po_negation : "",
used_opt->opt_long);
if (neg == neg_nomatch && negmatch (po, i, optstr, optlen))
fprintf (stderr, "%s%s%s\n",
po->po_long_opt_start,
po->po_negation,
po->po_optv[i]->opt_long);
found++;
case 2:
......@@ -254,6 +277,11 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
po->po_long_opt_start,
neg ? po->po_negation : "",
po->po_optv[i]->opt_long);
if (neg == neg_nomatch && negmatch (po, i, optstr, optlen))
fprintf (stderr, "%s%s%s\n",
po->po_long_opt_start,
po->po_negation,
po->po_optv[i]->opt_long);
}
}
}
......@@ -719,7 +747,9 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt,
if (arg == NULL)
{
if (opt->opt_arg == NULL)
if (opt->opt_default)
arg = opt->opt_default;
else if (opt->opt_arg == NULL)
arg = "1";
else
{
......@@ -737,7 +767,8 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt,
errtext = mu_strerror (rc);
if (opt->opt_long)
mu_parseopt_error (po, "--%s: %s", opt->opt_long, errtext);
mu_parseopt_error (po, "%s%s: %s", po->po_long_opt_start,
opt->opt_long, errtext);
else
mu_parseopt_error (po, "-%c: %s", opt->opt_short, errtext);
free (errmsg);
......
......@@ -70,7 +70,6 @@ libmh_a_SOURCES= \
mboxprop.c\
mh_alias_gram.c\
mh_alias_lex.c\
mh_argp.c\
mh_getopt.c\
mh_global.c\
mh_format.c\
......
......@@ -23,73 +23,41 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
static char doc[] = N_("GNU MH ali")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH ali");
static char args_doc[] = N_("ALIAS [ALIAS...]");
/* GNU options */
static struct argp_option options[] = {
{"alias", ARG_ALIAS, N_("FILE"), 0,
N_("use the additional alias FILE")},
{"noalias", ARG_NOALIAS, NULL, 0,
N_("do not read the system alias file") },
{"list", ARG_LIST, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("list each address on a separate line") },
{"normalize", ARG_NORMALIZE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("try to determine the official hostname for each address") },
{"user", ARG_USER, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("list the aliases that expand to given addresses") },
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "alias", MH_OPT_ARG, "aliasfile" },
{ "noalias", },
{ "list", MH_OPT_BOOL },
{ "normalize", MH_OPT_BOOL },
{ "user", MH_OPT_BOOL },
{ NULL }
};
static int list_mode;
static int user_mode;
static int normalize_mode;
static int nolist_mode;
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
alias_handler (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
{
case ARG_ALIAS:
mh_alias_read (arg, 1);
break;
case ARG_NOALIAS:
nolist_mode = 1;
break;
case ARG_LIST:
list_mode = is_true (arg);
break;
case ARG_NORMALIZE:
normalize_mode = is_true (arg);
break;
case ARG_USER:
user_mode = is_true (arg);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "alias", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("use the additional alias FILE"),
mu_c_string, NULL, alias_handler },
{ "noalias", 0, NULL, 0,
N_("do not read the system alias file"),
mu_c_int, &nolist_mode, NULL, "1" },
{ "list", 0, NULL, MU_OPTION_DEFAULT,
N_("list each address on a separate line"),
mu_c_bool, &list_mode },
{ "normalize", 0, NULL, MU_OPTION_DEFAULT,
N_("try to determine the official hostname for each address"),
mu_c_bool, &normalize_mode },
{ "user", 0, NULL, MU_OPTION_DEFAULT,
N_("list the aliases that expand to given addresses"),
mu_c_bool, &user_mode },
MU_OPTION_END
};
static int
getcols ()
getcols (void)
{
struct winsize ws;
......@@ -174,17 +142,10 @@ ali_print_name (char *name)
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);
argc -= index;
argv += index;
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
if (!nolist_mode)
mh_read_aliases ();
......
......@@ -19,81 +19,29 @@
#include <mh.h>
static char doc[] = N_("GNU MH anno")"\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 anno");
static char args_doc[] = N_("[MSGLIST]");
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("* annotate the message in place")},
{"noinplace", ARG_NOINPLACE, NULL, OPTION_HIDDEN, "" },
{"date", ARG_DATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("add FIELD: date header") },
{"nodate", ARG_NODATE, NULL, OPTION_HIDDEN, "" },
{"component", ARG_COMPONENT, N_("FIELD"), 0,
N_("add this FIELD to the message header") },
{"text", ARG_TEXT, N_("STRING"), 0,
N_("field value for the component") },
{ NULL }
};
struct mh_option mh_option[] = {
{ "inplace", MH_OPT_BOOL },
{ "date", MH_OPT_BOOL },
{ "component", MH_OPT_ARG, "field" },
{ "text", MH_OPT_ARG, "body" },
{ NULL }
};
static int inplace; /* Annotate the message in place */
//static int inplace; /* Annotate the message in place */
static int anno_date = 1; /* Add date to the annotation */
static char *component; /* header field */
static char *anno_text; /* header field value */
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 ARG_INPLACE:
mh_opt_notimpl_warning ("-inplace");
inplace = is_true (arg);
break;
case ARG_NOINPLACE:
mh_opt_notimpl_warning ("-noinplace");
inplace = 0;
break;
case ARG_DATE:
anno_date = is_true (arg);
break;
case ARG_NODATE:
anno_date = 0;
break;
case ARG_COMPONENT:
component = arg;
break;
case ARG_TEXT:
mh_quote (arg, &anno_text);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "inplace", 0, NULL, MU_OPTION_HIDDEN,
N_("annotate the message in place"),
mu_c_string, NULL, mh_opt_notimpl_warning },
{ "date", 0, NULL, MU_OPTION_DEFAULT,
N_("add FIELD: date header"),
mu_c_bool, &anno_date },
{ "component", 0, N_("FIELD"), MU_OPTION_DEFAULT,
N_("add this FIELD to the message header"),
mu_c_string, &component },
{ "text", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("field value for the component"),
mu_c_string, &anno_text },
MU_OPTION_END
};
int
anno (size_t n, mu_message_t msg, void *call_data)
......@@ -106,16 +54,20 @@ int
main (int argc, char **argv)
{
int rc;
int index;
mu_mailbox_t mbox;
mu_msgset_t msgset;
size_t len;
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 (anno_text)
{
char *arg = anno_text;
mh_quote (arg, &anno_text);
free (arg);
}
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
......@@ -152,9 +104,6 @@ main (int argc, char **argv)
if (len > 0 && component[len-1] == ':')
component[len-1] = 0;
argc -= index;
argv += index;
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
rc = mu_msgset_foreach_message (msgset, anno, NULL);
if (rc)
......
......@@ -18,40 +18,9 @@
#include <mh.h>
static char doc[] = N_("GNU MH burst")"\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 burst");
static char args_doc[] = N_("[MSGLIST]");
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("replace the source message with the table of contents, insert extracted messages after it") },
{"noinplace", ARG_NOINPLACE, 0, OPTION_HIDDEN, ""},
{"quiet", ARG_QUIET, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("be quiet about the messages that are not in digest format") },
{"noquiet", ARG_NOQUIET, 0, OPTION_HIDDEN, ""},
{"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("verbosely list the actions taken") },
{"noverbose", ARG_NOVERBOSE, 0, OPTION_HIDDEN, ""},
{"recursive", ARG_RECURSIVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("recursively expand MIME messages") },
{"norecursive", ARG_NORECURSIVE, 0, OPTION_HIDDEN, ""},
{"length", ARG_LENGTH, N_("NUMBER"), 0,
N_("set minimal length of digest encapsulation boundary (default 1)") },
{ NULL }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "inplace", MH_OPT_BOOL },
{ "quiet", MH_OPT_BOOL },
{ "verbose", MH_OPT_BOOL },
{ NULL }
};
/* Command line switches */
int inplace;
int quiet;
......@@ -61,59 +30,24 @@ int eb_min_length = 1; /* Minimal length of encapsulation boundary */
#define VERBOSE(c) do { if (verbose) { printf c; putchar ('\n'); } } while (0)
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 ARG_INPLACE:
inplace = is_true (arg);
break;
case ARG_NOINPLACE:
inplace = 0;
break;
case ARG_LENGTH:
eb_min_length = strtoul (arg, NULL, 0);
if (eb_min_length == 0)
eb_min_length = 1;
break;
case ARG_VERBOSE:
verbose = is_true (arg);
break;
case ARG_NOVERBOSE:
verbose = 0;
break;
case ARG_RECURSIVE:
recursive = is_true (arg);
break;
case ARG_NORECURSIVE:
recursive = 0;
break;
case ARG_QUIET:
quiet = is_true (arg);
break;
case ARG_NOQUIET:
quiet = 0;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "inplace", 0, NULL, MU_OPTION_DEFAULT,
N_("replace the source message with the table of contents, insert extracted messages after it"),
mu_c_bool, &inplace },
{ "quiet", 0, NULL, MU_OPTION_DEFAULT,
N_("be quiet about the messages that are not in digest format"),
mu_c_bool, &quiet },
{ "verbose", 0, NULL, MU_OPTION_DEFAULT,
N_("verbosely list the actions taken"),
mu_c_bool, &verbose },
{ "recursive", 0, NULL, MU_OPTION_DEFAULT,
N_("recursively expand MIME messages"),
mu_c_bool, &recursive },
{ "length", 0, N_("NUM"), MU_OPTION_DEFAULT,
N_("set minimal length of digest encapsulation boundary (default 1)"),
mu_c_int, &eb_min_length },
MU_OPTION_END
};
/* General-purpose data structures */
struct burst_map
......@@ -713,7 +647,7 @@ finalize_inplace (size_t lastuid)
int
main (int argc, char **argv)
{
int index, rc;
int rc;
mu_mailbox_t mbox;
mu_msgset_t msgset;
const char *tempfolder = mh_global_profile_get ("Temp-Folder", ".temp");
......@@ -721,12 +655,10 @@ 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, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
if (eb_min_length == 0)
eb_min_length = 1;
VERBOSE ((_("Opening folder `%s'"), mh_current_folder ()));
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
......
......@@ -21,143 +21,73 @@
#include <sys/types.h>
#include <sys/stat.h>
static char doc[] = N_("GNU MH comp")"\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 comp");
static char args_doc[] = N_("[MSG]");
/* GNU options */
static struct argp_option options[] = {
{"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")},
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{"file", ARG_FILE, N_("FILE"), 0,
N_("use FILE as the message draft")},
{"editor", ARG_EDITOR, N_("PROG"), 0,
N_("set the editor program to use")},
{"noedit", ARG_NOEDIT, 0, 0,
N_("suppress the initial edit")},
{"form", ARG_FORM, N_("FILE"), 0,
N_("read format from given file")},
{"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") },
{"nouse", ARG_NOUSE, NULL, OPTION_HIDDEN, ""},
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "build" },
{ "file", MH_OPT_ARG, "draftfile" },
{ "form", MH_OPT_ARG, "formatfile" },
{ "draftfolder", MH_OPT_ARG, "folder" },
{ "nodraftfolder" },
{ "draftmessage" },
{ "editor", MH_OPT_ARG, "program" },
{ "noedit" },
{ "whatnowproc", MH_OPT_ARG, "program" },
{ "nowhatnowproc" },
{ "use" },
{ NULL }
};
struct mh_whatnow_env wh_env = { 0 };
static int initial_edit = 1;
static const char *whatnowproc;
static int nowhatnowproc;
char *formfile;
static int build_only = 0; /* --build flag */
static int use_draft = 0; /* --use flag */
static int build_only = 0; /* -build flag */
static int use_draft = 0; /* -use flag */
static char *draftmessage = "new";
static const char *draftfolder = NULL;
static int folder_set; /* Folder is set on the command line */
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 ARGP_KEY_INIT:
draftfolder = mh_global_profile_get ("Draft-Folder", NULL);
whatnowproc = mh_global_profile_get ("whatnowproc", NULL);
break;
case ARG_BUILD:
build_only = 1;
break;
case ARG_DRAFTFOLDER:
draftfolder = arg;
break;
case ARG_EDITOR:
wh_env.editor = arg;
break;
case ARG_FOLDER:
mh_set_current_folder (arg);
folder_set = 1;
break;
case ARG_FORM:
mh_find_file (arg, &formfile);
break;
case ARG_DRAFTMESSAGE:
draftmessage = arg;
break;
case ARG_USE:
use_draft = is_true (arg);
draftmessage = "cur";
break;
case ARG_NOUSE:
use_draft = 0;
break;
}
case ARG_FILE:
static void
set_file (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
wh_env.file = mh_expand_name (NULL, arg, NAME_ANY);
break;
case ARG_NODRAFTFOLDER:
draftfolder = NULL;
break;
case ARG_NOEDIT:
initial_edit = 0;
break;
case ARG_WHATNOWPROC:
whatnowproc = arg;
break;
case ARG_NOWHATNOWPROC:
nowhatnowproc = 1;
break;
case ARGP_KEY_FINI:
if (!formfile)
mh_find_file ("components", &formfile);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "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 },
{ "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify folder to operate upon"),
mu_c_string, NULL, set_folder },
{ "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("use FILE as the message draft"),
mu_c_string, NULL, set_file },
{ "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" },
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read format from given file"),
mu_c_string, &formfile, mh_opt_find_file },
{ "whatnowproc", 0, N_("PROG"), MU_OPTION_DEFAULT,
N_("set the replacement for whatnow program"),
mu_c_string, &whatnowproc },
{ "nowhatnowproc", 0, NULL, MU_OPTION_DEFAULT,
N_("don't run whatnowproc"),
mu_c_string, &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
};
/* Copy Nth message from mailbox MBOX to FILE. */
int
copy_message (mu_mailbox_t mbox, size_t n, const char *file)
......@@ -201,14 +131,18 @@ copy_message (mu_mailbox_t mbox, size_t n, const char *file)
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);
draftfolder = mh_global_profile_get ("Draft-Folder", NULL);
whatnowproc = mh_global_profile_get ("whatnowproc", NULL);
mh_getopt (&argc, &argv, options, 0,
args_doc, prog_doc, NULL);
if (use_draft)
draftmessage = "cur";
if (!formfile)
mh_find_file ("components", &formfile);
if (wh_env.file)
{
......@@ -226,14 +160,14 @@ main (int argc, char **argv)
{
if (build_only || !draftfolder)
{
switch (argc - index)
switch (argc)
{
case 0:
wh_env.file = mh_expand_name (NULL, "draft", 0);
break;
case 1:
wh_env.file = mh_expand_name (NULL, argv[index], 0);
wh_env.file = mh_expand_name (NULL, argv[0], 0);
break;
default:
......@@ -245,7 +179,7 @@ main (int argc, char **argv)
{
/* Comp accepts a `file', and it will, if given
`-draftfolder +folder' treat this arguments as `msg'. */
if (use_draft || index < argc)
if (use_draft || argc)
{
mu_msgset_t msgset;
mu_mailbox_t mbox;
......@@ -253,7 +187,7 @@ main (int argc, char **argv)
mbox = mh_open_folder (draftfolder,
MU_STREAM_RDWR|MU_STREAM_CREAT);
mh_msgset_parse (&msgset, mbox,
argc - index, argv + index,
argc, argv,
use_draft ? "cur" : "new");
if (!mh_msgset_single_message (msgset))
{
......@@ -271,13 +205,13 @@ main (int argc, char **argv)
}
wh_env.draftfile = wh_env.file;
if (folder_set && index < argc)
if (folder_set && argc)
{
mu_msgset_t msgset;
mu_mailbox_t mbox;
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
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!"));
......@@ -304,7 +238,7 @@ main (int argc, char **argv)
}
}
/* Exit immediately if --build is given */
/* Exit immediately if -build is given */
if (build_only || nowhatnowproc)
return 0;
......
......@@ -19,37 +19,33 @@
#include <mh.h>
static char doc[] = N_("GNU MH fmtcheck")"\v"
N_("Use -help to obtain the list of traditional MH options.");
/* GNU options */
static struct argp_option options[] = {
{"form", ARG_FORM, N_("FILE"), 0,
N_("read format from given file")},
{"format", ARG_FORMAT, N_("FORMAT"), 0,
N_("use this format string")},
{"dump", ARG_DUMP, NULL, 0,
N_("dump the listing of compiled format code")},
{ "debug", ARG_DEBUG, NULL, 0,
N_("enable parser debugging output"),},
{ NULL }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "form", MH_OPT_ARG, "formatfile" },
{ "format", MH_OPT_ARG, "string" },
{ NULL }
};
static char prog_doc[] = N_("GNU MH fmtcheck");
char *format_str;
static mh_format_t format;
typedef int (*action_fp) (void);
int dump_option;
int debug_option;
static struct mu_option options[] = {
{ "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 },
{ "dump", 0, NULL, MU_OPTION_HIDDEN,
N_("dump the listing of compiled format code"),
mu_c_bool, &dump_option },
{ "debug", 0, NULL, MU_OPTION_DEFAULT,
N_("enable parser debugging output"),
mu_c_bool, &debug_option },
MU_OPTION_END
};
static int
action_dump ()
action_dump (void)
{
if (!format_str)
{
......@@ -60,49 +56,18 @@ action_dump ()
return 0;
}
static action_fp action = action_dump;
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case ARG_FORM:
mh_read_formfile (arg, &format_str);
break;
case ARG_FORMAT:
format_str = arg;
break;
case ARG_DUMP:
action = action_dump;
break;
case ARG_DEBUG:
mh_format_debug (1);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
int
main (int argc, char **argv)
{
/* Native Language Support */
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, NULL, doc,
opt_handler, NULL, NULL);
mh_getopt (&argc, &argv, options, 0, NULL, prog_doc, NULL);
mh_format_debug (debug_option);
if (format_str && mh_format_parse (format_str, &format))
{
mu_error (_("Bad format string"));
exit (1);
}
return (*action) ();
return action_dump ();
}
......
......@@ -28,78 +28,16 @@
#include <dirent.h>
static char doc[] = N_("GNU MH folder")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH folder");
static char args_doc[] = N_("[ACTION] [MSG]");
static struct argp_option options[] = {
{N_("Actions are:"), 0, 0, OPTION_DOC, NULL, 0 },
{"print", ARG_PRINT, NULL, 0,
N_("list the folders (default)"), 1 },
{"list", ARG_LIST, NULL, 0,
N_("list the contents of the folder stack"), 1},
{"pack", ARG_PACK, N_("NUMBER"), OPTION_ARG_OPTIONAL,
N_("remove holes in message numbering, begin numbering from NUMBER (default: first message number)"), 1},
{"push", ARG_PUSH, N_("FOLDER"), OPTION_ARG_OPTIONAL,
N_("push the folder on the folder stack. If FOLDER is specified, it is pushed. "
"Otherwise, if a folder is given in the command line (via + or --folder), "
"it is pushed on stack. Otherwise, the current folder and the top of the folder "
"stack are exchanged"), 1},
{"pop", ARG_POP, NULL, 0,
N_("pop the folder off the folder stack"), 1},
{N_("Options are:"), 0, 0, OPTION_DOC, NULL, 2 },
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon"), 3},
{"all", ARG_ALL, NULL, 0,
N_("list all folders"), 3},
{"create", ARG_CREATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("create non-existing folders"), 3},
{"nocreate", ARG_NOCREATE, NULL, OPTION_HIDDEN, ""},
{"fast", ARG_FAST, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("list only the folder names"), 3},
{"nofast", ARG_NOFAST, NULL, OPTION_HIDDEN, ""},
{"header", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("print the header line"), 3},
{"noheader", ARG_NOHEADER, NULL, OPTION_HIDDEN, ""},
{"recurse",ARG_RECURSIVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("scan folders recursively"), 3},
{"norecurse", ARG_NORECURSIVE, NULL, OPTION_HIDDEN, ""},
{"total", ARG_TOTAL, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("output the total statistics"), 3},
{"nototal", ARG_NOTOTAL, NULL, OPTION_HIDDEN, ""},
{"verbose", ARG_VERBOSE, NULL, 0,
N_("verbosely list actions taken"), 3},
{"dry-run", ARG_DRY_RUN, NULL, 0,
N_("do nothing, print what would be done (with --pack)"), 3},
{NULL},
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "print" },
{ "list" },
{ "push" },
{ "pop" },
{ "all" },
{ "pack" },
{ "create", MH_OPT_BOOL },
{ "fast", MH_OPT_BOOL },
{ "header", MH_OPT_BOOL },
{ "recurse", MH_OPT_BOOL },
{ "total", MH_OPT_BOOL },
{ NULL }
};
typedef int (*folder_action) (void);
typedef int (*folder_action) ();
static int action_print ();
static int action_list ();
static int action_push ();
static int action_pop ();
static int action_pack ();
static int action_print (void);
static int action_list (void);
static int action_push (void);
static int action_pop (void);
static int action_pack (void);
static folder_action action = action_print;
int show_all = 0; /* List all folders. Raised by --all switch */
......@@ -121,110 +59,105 @@ const char *push_folder; /* Folder name to push on stack */
const char *mh_seq_name; /* Name of the mh sequence file (defaults to
.mh_sequences) */
int has_folder; /* Folder has been explicitely given */
int recurse_option = 0;
size_t max_depth = 1; /* Maximum recursion depth (0 means infinity) */
#define OPTION_IS_SET(opt) ((opt) == -1 ? show_all : opt)
static int
opt_handler (int key, char *arg, struct argp_state *state)
void
set_action (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
if (strcmp (opt->opt_long, "print") == 0)
action = action_print;
else if (strcmp (opt->opt_long, "pack") == 0)
{
case ARG_DRY_RUN:
dry_run++;
break;
case ARG_PACK:
action = action_pack;
if (arg)
{
char *p;
pack_start = strtoul (arg, &p, 10);
if (*p)
argp_error (state, _("invalid number"));
if (mu_str_to_c (arg, mu_c_size, &pack_start, NULL))
{
mu_parseopt_error (po, _("%s: invalid number"), arg);
exit (po->po_exit_error);
}
break;
case ARG_PRINT:
action = action_print;
break;
case ARG_LIST:
}
}
else if (strcmp (opt->opt_long, "list") == 0)
action = action_list;
break;
case ARG_PUSH:
else if (strcmp (opt->opt_long, "push") == 0)
{
action = action_push;
if (arg)
{
push_folder = mh_current_folder ();
mh_set_current_folder (arg);
}
break;
case ARG_POP:
}
else if (strcmp (opt->opt_long, "pop") == 0)
action = action_pop;
break;
case ARG_ALL:
show_all = 1;
break;
case ARG_CREATE:
create_flag = is_true (arg);
break;
case ARG_NOCREATE:
create_flag = 0;
case ARG_FAST:
fast_mode = is_true (arg);
break;
case ARG_NOFAST:
fast_mode = 0;
break;
case ARG_HEADER:
print_header = is_true (arg);
break;
case ARG_NOHEADER:
print_header = 0;
break;
case ARG_RECURSIVE:
max_depth = is_true (arg) ? 0 : 1;
break;
case ARG_NORECURSIVE:
max_depth = 0;
break;
case ARG_TOTAL:
print_total = is_true (arg);
break;
case ARG_NOTOTAL:
print_total = 0;
break;
else
abort ();
}
case ARG_FOLDER:
void
set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
has_folder = 1;
push_folder = mh_current_folder ();
mh_set_current_folder (arg);
break;
case ARG_VERBOSE:
verbose++;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
MU_OPTION_GROUP (N_("Actions are:")),
{ "print", 0, NULL, MU_OPTION_DEFAULT,
N_("list the folders (default)"),
mu_c_string, NULL, set_action },
{ "list", 0, NULL, MU_OPTION_DEFAULT,
N_("list the contents of the folder stack"),
mu_c_string, NULL, set_action },
{ "pack", 0, N_("NUMBER"), MU_OPTION_ARG_OPTIONAL,
N_("remove holes in message numbering, begin numbering from NUMBER (default: first message number)"),
mu_c_string, NULL, set_action },
{ "push", 0, N_("FOLDER"), MU_OPTION_ARG_OPTIONAL,
N_("push the folder on the folder stack. If FOLDER is specified, it is pushed. "
"Otherwise, if a folder is given in the command line (via + or --folder), "
"it is pushed on stack. Otherwise, the current folder and the top of the folder "
"stack are exchanged"),
mu_c_string, NULL, set_action },
{ "pop", 0, NULL, MU_OPTION_DEFAULT,
N_("pop the folder off the folder stack"),
mu_c_string, NULL, set_action },
MU_OPTION_GROUP (N_("Options are:")),
{ "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify folder to operate upon"),
mu_c_string, NULL, set_folder },
{ "all", 0, NULL, MU_OPTION_DEFAULT,
N_("list all folders"),
mu_c_bool, &show_all },
{ "create", 0, NULL, MU_OPTION_DEFAULT,
N_("create non-existing folders"),
mu_c_bool, &create_flag },
{ "fast", 0, NULL, MU_OPTION_DEFAULT,
N_("list only the folder names"),
mu_c_bool, &fast_mode },
{ "header", 0, NULL, MU_OPTION_DEFAULT,
N_("print the header line"),
mu_c_bool, &print_header },
{ "recurse",0, NULL, MU_OPTION_DEFAULT,
N_("scan folders recursively"),
mu_c_bool, &recurse_option },
{ "total", 0, NULL, MU_OPTION_DEFAULT,
N_("output the total statistics"),
mu_c_bool, &print_total },
{ "verbose", 0, NULL, MU_OPTION_DEFAULT,
N_("verbosely list actions taken"),
mu_c_bool, &verbose },
{ "dry-run", 0, NULL, MU_OPTION_DEFAULT,
N_("do nothing, print what would be done (with --pack)"),
mu_c_bool, &dry_run },
MU_OPTION_END
};
/* ************************************************************* */
/* Printing */
......@@ -430,19 +363,19 @@ _folder_name_printer (void *item, void *data)
}
static void
print_all ()
print_all (void)
{
mu_list_foreach (folder_info_list, _folder_info_printer, NULL);
}
static void
print_fast ()
print_fast (void)
{
mu_list_foreach (folder_info_list, _folder_name_printer, NULL);
}
static int
action_print ()
action_print (void)
{
const char *folder_dir = mu_folder_directory ();
mh_seq_name = mh_global_profile_get ("mh-sequences", MH_SEQUENCES_FILE);
......@@ -502,7 +435,7 @@ action_print ()
/* Listing */
static int
action_list ()
action_list (void)
{
const char *stack = mh_global_context_get ("Folder-Stack", NULL);
......@@ -598,7 +531,7 @@ pop_val (size_t *pc, char ***pv)
}
static int
action_push ()
action_push (void)
{
size_t c;
char **v;
......@@ -623,7 +556,7 @@ action_push ()
}
static int
action_pop ()
action_pop (void)
{
size_t c;
char **v;
......@@ -849,7 +782,7 @@ fixup_private (const char *name, const char *value, void *data)
}
int
action_pack ()
action_pack (void)
{
const char *folder_dir = mh_expand_name (NULL, mh_current_folder (),
NAME_ANY);
......@@ -959,9 +892,9 @@ 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, options, 0, args_doc, prog_doc, NULL);
if (recurse_option)
max_depth = 0;
/* If folder is invoked by a name ending with "s" (e.g., folders),
`-all' is assumed */
......
......@@ -19,79 +19,9 @@
#include <mh.h>
static char doc[] = N_("GNU MH forw")"\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 forw");
static char args_doc[] = N_("[MSGLIST]");
/* GNU options */
static struct argp_option options[] = {
{"annotate", ARG_ANNOTATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("add Forwarded: header to each forwarded message")},
{"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")},
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{"editor", ARG_EDITOR, N_("PROG"), 0,
N_("set the editor program to use")},
{"noedit", ARG_NOEDIT, 0, 0,
N_("suppress the initial edit")},
{"file", ARG_FILE, N_("FILE"), 0,
N_("read message from FILE")},
{"format", ARG_FORMAT, N_("BOOL"), 0,
N_("format messages")},
{"noformat", ARG_NOFORMAT, NULL, 0,
N_("undo the effect of the last --format option") },
{"form", ARG_FORM, N_("FILE"), 0,
N_("read format from given file")},
{"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") },
{"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("* annotate the message in place")},
{"noinplace", ARG_NOINPLACE, 0, OPTION_HIDDEN, "" },
{"mime", ARG_MIME, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("use MIME encapsulation") },
{"nomime", ARG_NOMIME, NULL, OPTION_HIDDEN, "" },
{"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") },
{"nouse", ARG_NOUSE, N_("BOOL"), OPTION_HIDDEN, "" },
{NULL},
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "annotate", MH_OPT_BOOL },
{ "build" },
{ "file", MH_OPT_ARG, "msgfile" },
{ "form", MH_OPT_ARG, "formatfile" },
{ "format", MH_OPT_BOOL },
{ "draftfolder", MH_OPT_ARG, "folder" },
{ "nodraftfolder" },
{ "draftmessage" },
{ "editor", MH_OPT_ARG, "program" },
{ "noedit" },
{ "filter", MH_OPT_ARG, "program" },
{ "inplace", MH_OPT_BOOL },
{ "whatnowproc", MH_OPT_ARG, "program" },
{ "nowhatnowproc" },
{ "mime", MH_OPT_BOOL },
{ NULL }
};
enum encap_type
{
encap_clear,
......@@ -120,123 +50,99 @@ static char *input_file; /* input file name (--file option) */
static mu_msgset_t msgset;
static mu_mailbox_t mbox;
static int
opt_handler (int key, char *arg, struct argp_state *state)
static void
set_filter (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
{
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_FILE:
input_file = arg;
break;
case ARG_DRAFTFOLDER:
draftfolder = arg;
break;
case ARG_NODRAFTFOLDER:
draftfolder = NULL;
break;
case ARG_DRAFTMESSAGE:
draftmessage = arg;
break;
case ARG_USE:
use_draft = is_true (arg);
break;
case ARG_NOUSE:
use_draft = 0;
break;
case ARG_WIDTH:
width = strtoul (arg, NULL, 0);
if (!width)
{
argp_error (state, _("invalid width"));
exit (1);
}
break;
case ARG_EDITOR:
wh_env.editor = arg;
break;
mh_find_file (arg, &mhl_filter_file);
encap = encap_mhl;
}
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
static void
clear_filter (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
mhl_filter_file = NULL;
encap = encap_clear;
}
case ARG_FORM:
mh_find_file (arg, &formfile);
break;
static void
set_mime (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
if (strcmp (arg, "1") == 0)
encap = encap_mime;
else
encap = encap_clear;
}
case ARG_FORMAT:
if (is_true (arg))
static void
set_format (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
if (arg)
{
encap = encap_mhl;
mh_find_file ("mhl.forward", &mhl_filter_file);
}
else
encap = encap_clear;
break;
case ARG_NOFORMAT:
encap = encap_clear;
break;
case ARG_FILTER:
mh_find_file (arg, &mhl_filter_file);
encap = encap_mhl;
break;
case ARG_MIME:
if (is_true (arg))
{
encap = encap_mime;
break;
}
/*FALLTHRU*/
case ARG_NOMIME:
if (encap == encap_mime)
encap = encap_clear;
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 (!formfile)
mh_find_file ("forwcomps", &formfile);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "annotate", 0, NULL, MU_OPTION_DEFAULT,
N_("add Forwarded: header to each forwarded message"),
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 },
{ "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" },
{ "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read message from FILE"),
mu_c_string, &input_file },
{ "format", 0, NULL, MU_OPTION_DEFAULT,
N_("format messages"),
mu_c_bool, NULL, set_format },
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read format from given file"),
mu_c_string, &formfile, mh_opt_find_file },
{ "filter", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("use filter FILE to preprocess the body of the message"),
mu_c_string, NULL, set_filter },
{ "nofilter", 0, NULL, MU_OPTION_DEFAULT,
N_("undo the effect of the last --filter option"),
mu_c_string, NULL, clear_filter },
{ "inplace", 0, NULL, MU_OPTION_HIDDEN,
N_("annotate the message in place"),
mu_c_bool, NULL, mh_opt_notimpl_warning },
{ "mime", 0, NULL, MU_OPTION_DEFAULT,
N_("use MIME encapsulation"),
mu_c_bool, NULL, set_mime },
{ "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, &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
};
struct format_data
{
int num;
......@@ -475,17 +381,17 @@ finish_draft ()
int
main (int argc, char **argv)
{
int index, rc;
int rc;
/* 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;
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 (!formfile)
mh_find_file ("forwcomps", &formfile);
if (input_file)
{
......
......@@ -20,71 +20,14 @@
#include <mh.h>
#include "muscript.h"
static char doc[] = N_("GNU MH inc")"\v"
N_("Debug flags are:\n\
static char prog_doc[] = N_("GNU MH inc");
static char extra_doc[] = N_("Debug flags are:\n\
g - guile stack traces\n\
t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\
i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\
l - sieve action logs\n\n\
Use -help to obtain the list of traditional MH options.");
l - sieve action logs");
static char args_doc[] = N_("[+FOLDER]");
/* GNU options */
static struct argp_option options[] = {
{"file", ARG_FILE, N_("FILE"), 0,
N_("incorporate mail from named file")},
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to incorporate mail to")},
{"audit", ARG_AUDIT, N_("FILE"), 0,
N_("enable audit")},
{"noaudit", ARG_NOAUDIT, 0, 0,
N_("disable audit")},
{"changecur", ARG_CHANGECUR, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("mark first incorporated message as current (default)")},
{"nochangecur", ARG_NOCHANGECUR, NULL, OPTION_HIDDEN, ""},
{"form", ARG_FORM, N_("FILE"), 0,
N_("read format from given file")},
{"format", ARG_FORMAT, N_("FORMAT"), 0,
N_("use this format string")},
{"truncate", ARG_TRUNCATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("truncate source mailbox after incorporating (default)")},
{"notruncate", ARG_NOTRUNCATE, NULL, OPTION_HIDDEN, ""},
{"moveto", ARG_MOVETO, N_("MAILBOX"), 0,
N_("move incorporated messages to MAILBOX instead of deleting them") },
{"width", ARG_WIDTH, N_("NUMBER"), 0,
N_("set output width")},
{"quiet", ARG_QUIET, 0, 0,
N_("be quiet")},
{"notify", ARG_NOTIFY,N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("enable biff notification"), },
{"language",ARG_LANG, N_("LANG"), 0,
N_("set language for the --script option") },
{"script", ARG_SCRIPT,N_("FILE"), 0,
N_("filter incoming messages using script FILE") },
{"debug", ARG_DEBUG, N_("FLAGS"), 0,
N_("enable debugging") },
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "audit", MH_OPT_ARG, "audit-file" },
{ "noaudit" },
{ "changecur", MH_OPT_BOOL },
{ "file", MH_OPT_ARG, "input-file" },
{ "form", MH_OPT_ARG, "format-file" },
{ "format", MH_OPT_ARG, "string" },
{ "truncate", MH_OPT_BOOL },
{ "moveto", MH_OPT_ARG, "folder" },
{ "width", MH_OPT_ARG, "number" },
{ "notify", MH_OPT_BOOL },
{ "quiet" },
{ "language", MH_OPT_ARG, "lang" },
{ "script", MH_OPT_ARG, "file" },
{ "debug", MH_OPT_ARG, "flags" },
{ NULL }
};
static char *format_str = mh_list_format;
static int width = 80;
static mu_list_t input_file_list;
......@@ -99,53 +42,10 @@ static const char *move_to_mailbox;
static const char *script_file;
static const char *script_lang;
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
add_file (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
int rc;
char *p;
switch (key)
{
case ARGP_KEY_FINI:
if (!append_folder)
append_folder = mh_global_profile_get ("Inbox", "inbox");
break;
case ARG_AUDIT:
audit_file = arg;
break;
case ARG_NOAUDIT:
audit_file = NULL;
break;
case ARG_CHANGECUR:
changecur = is_true (arg);
break;
case ARG_DEBUG:
if (mu_script_debug_flags (arg, &p))
argp_error (state, _("invalid debug flag near %s"), p);
break;
case ARG_NOCHANGECUR:
changecur = 0;
break;
case ARG_FOLDER:
append_folder = arg;
break;
case ARG_FORM:
mh_read_formfile (arg, &format_str);
break;
case ARG_FORMAT:
format_str = arg;
break;
case ARG_FILE:
if (!input_file_list)
{
rc = mu_list_create (&input_file_list);
......@@ -156,57 +56,75 @@ opt_handler (int key, char *arg, struct argp_state *state)
exit (1);
}
}
rc = mu_list_append (input_file_list, arg);
rc = mu_list_append (input_file_list, mu_strdup (arg));
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", arg, rc);
exit (1);
}
break;
case ARG_TRUNCATE:
truncate_source = is_true (arg);
break;
case ARG_NOTRUNCATE:
truncate_source = 0;
break;
}
case ARG_MOVETO:
move_to_mailbox = arg;
break;
static void
set_debug (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
char *p;
case ARG_WIDTH:
width = strtoul (arg, NULL, 0);
if (!width)
if (mu_script_debug_flags (arg, &p))
{
argp_error (state, _("invalid width"));
exit (1);
}
break;
case ARG_QUIET:
quiet = 1;
break;
case ARG_NOTIFY:
notify = is_true (arg);;
break;
case ARG_LANG:
script_lang = arg;
break;
case ARG_SCRIPT:
script_file = arg;
break;
default:
return ARGP_ERR_UNKNOWN;
mu_parseopt_error (po, _("invalid debug flag near %s"), p);
exit (po->po_exit_error);
}
return 0;
}
static struct mu_option options[] = {
{ "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("incorporate mail from named file"),
mu_c_string, NULL, add_file },
{ "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify folder to incorporate mail to"),
mu_c_string, &append_folder },
{ "audit", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("enable audit"),
mu_c_string, &audit_file },
{ "noaudit", 0, NULL, MU_OPTION_DEFAULT,
N_("disable audit"),
mu_c_string, &audit_file, mh_opt_clear_string },
{ "changecur", 0, NULL, MU_OPTION_DEFAULT,
N_("mark first incorporated message as current (default)"),
mu_c_bool, &changecur },
{ "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 },
{ "truncate", 0, NULL, MU_OPTION_DEFAULT,
N_("truncate source mailbox after incorporating (default)"),
mu_c_bool, &truncate_source },
{ "moveto", 0, N_("MAILBOX"), MU_OPTION_DEFAULT,
N_("move incorporated messages to MAILBOX instead of deleting them"),
mu_c_string, &move_to_mailbox },
{ "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set output width"),
mu_c_int, &width },
{ "quiet", 0, NULL, MU_OPTION_DEFAULT,
N_("be quiet"),
mu_c_bool, &quiet },
{ "notify", 0, NULL, MU_OPTION_DEFAULT,
N_("enable biff notification"),
mu_c_bool, &notify },
{ "language", 0, N_("LANG"), MU_OPTION_DEFAULT,
N_("set language for the --script option"),
mu_c_string, &script_lang },
{ "script", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("filter incoming messages using script FILE"),
mu_c_string, &script_file },
{ "debug", 0, N_("FLAGS"), MU_OPTION_DEFAULT,
N_("enable debugging"),
mu_c_string, 0, set_debug },
MU_OPTION_END
};
void
list_message (mh_format_t *format, mu_mailbox_t mbox, size_t msgno,
size_t width)
......@@ -430,9 +348,10 @@ 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, extra_doc);
if (!append_folder)
append_folder = mh_global_profile_get ("Inbox", "inbox");
mu_registrar_set_default_scheme ("mh");
/* Inc sets missing cur to 1 */
......
......@@ -17,41 +17,17 @@
#include <mh.h>
static char doc[] = N_("GNU MH install-mh")"\v"
N_("Use -help to obtain the list of traditional MH options.");
/* GNU options */
static struct argp_option options[] = {
{"auto", ARG_AUTO, NULL, 0, N_("do not ask for anything")},
{"compat", ARG_COMPAT, NULL, OPTION_HIDDEN, ""},
{NULL}
};
struct mh_option mh_option[] = {
{ "auto" },
{ "compat" },
{ NULL }
};
static char prog_doc[] = N_("GNU MH install-mh");
int automode;
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case ARG_AUTO:
automode = 1;
break;
case ARG_COMPAT:
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "auto", 0, NULL, MU_OPTION_DEFAULT,
N_("do not ask for anything"),
mu_c_bool, &automode },
{ "compat", 0, NULL, MU_OPTION_HIDDEN, "", mu_c_void },
MU_OPTION_END
};
int
main (int argc, char **argv)
......@@ -62,10 +38,8 @@ main (int argc, char **argv)
/* Native Language Support */
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_auto_install = 0;
mh_argp_parse (&argc, &argv, 0, options, mh_option, NULL, doc,
opt_handler, NULL, NULL);
mh_getopt (&argc, &argv, options, 0, NULL, prog_doc, NULL);
name = getenv ("MH");
if (name)
......
......@@ -17,106 +17,78 @@
#include <mh.h>
static char doc[] = N_("GNU MH mark")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH mark");
static char args_doc[] = N_("[MSGLIST]");
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{"sequence", ARG_SEQUENCE, N_("NAME"), 0,
N_("specify sequence name to operate upon")},
{"add", ARG_ADD, NULL, 0,
N_("add messages to the sequence")},
{"delete", ARG_DELETE, NULL, 0,
N_("delete messages from the sequence")},
{"list", ARG_LIST, NULL, 0,
N_("list the sequences")},
{"public", ARG_PUBLIC, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("create public sequence")},
{"nopublic", ARG_NOPUBLIC, NULL, OPTION_HIDDEN, "" },
{"zero", ARG_ZERO, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("empty the sequence before adding messages")},
{"nozero", ARG_NOZERO, NULL, OPTION_HIDDEN, "" },
{NULL}
};
struct mh_option mh_option[] = {
{ "sequence" },
{ "add" },
{ "delete" },
{ "list" },
{ "public", MH_OPT_BOOL },
{ "zero", MH_OPT_BOOL },
{ NULL }
};
enum action_type
{
action_undef,
action_list,
action_add,
action_delete
};
static enum action_type action = action_undef; /* Action to perform */
static int action; /* Action to perform */
static int seq_flags = 0; /* Create public sequences;
Do not zero the sequence before addition */
static mu_list_t seq_list; /* List of sequence names to operate upon */
static const char *mbox_dir;
static int public_option = -1;
static int zero_option = -1;
static void
add_sequence (char *name)
set_action_add (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);
action = action_add;
}
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
set_action_delete (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
switch (key)
{
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
case ARG_SEQUENCE:
add_sequence (arg);
break;
case ARG_ADD:
case ARG_DELETE:
case ARG_LIST:
action = key;
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;
action = action_delete;
}
case ARG_NOZERO:
seq_flags &= ~SEQ_ZERO;
break;
static void
set_action_list (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
action = action_list;
}
default:
return ARGP_ERR_UNKNOWN;
static void
add_sequence (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);
}
return 0;
mu_list_append (seq_list, mu_strdup (arg));
}
static struct mu_option options[] = {
{ "sequence", 0, N_("NAME"), MU_OPTION_DEFAULT,
N_("specify sequence name to operate upon"),
mu_c_string, NULL, add_sequence },
{ "add", 0, NULL, MU_OPTION_DEFAULT,
N_("add messages to the sequence"),
mu_c_string, NULL, set_action_add },
{ "delete", 0, NULL, MU_OPTION_DEFAULT,
N_("delete messages from the sequence"),
mu_c_string, NULL, set_action_delete },
{ "list", 0, NULL, MU_OPTION_DEFAULT,
N_("list the sequences"),
mu_c_string, NULL, set_action_list },
{ "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
};
struct mark_closure
{
......@@ -125,7 +97,7 @@ struct mark_closure
};
static int
action_add (void *item, void *data)
do_add (void *item, void *data)
{
struct mark_closure *clos = data;
mh_seq_add (clos->mbox, (char *)item, clos->msgset, seq_flags);
......@@ -133,7 +105,7 @@ action_add (void *item, void *data)
}
static int
action_delete (void *item, void *data)
do_delete (void *item, void *data)
{
struct mark_closure *clos = data;
mh_seq_delete (clos->mbox, (char *)item, clos->msgset, seq_flags);
......@@ -141,7 +113,7 @@ action_delete (void *item, void *data)
}
static int
action_list (void *item, void *data)
do_list (void *item, void *data)
{
struct mark_closure *clos = data;
char *name = item;
......@@ -190,16 +162,38 @@ list_all (mu_mailbox_t mbox)
int
main (int argc, char **argv)
{
int index;
mu_msgset_t msgset;
mu_mailbox_t mbox;
mu_url_t url;
struct mark_closure clos;
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 (public_option == -1)
/* use default */;
else if (public_option)
seq_flags &= ~SEQ_PRIVATE;
else
seq_flags |= SEQ_PRIVATE;
if (zero_option == -1)
/* use default */;
else if (zero_option)
seq_flags |= SEQ_ZERO;
else
seq_flags &= ~SEQ_ZERO;
if (action == action_undef)
{
/* If no explicit action is given, assume -add if a sequence
was specified, and -list otherwise. */
if (mu_list_is_empty (seq_list))
action = action_list;
else
action = action_add;
}
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mu_mailbox_get_url (mbox, &url);
......@@ -207,8 +201,6 @@ main (int argc, char **argv)
if (memcmp (mbox_dir, "mh:", 3) == 0)
mbox_dir += 3;
argc -= index;
argv += index;
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
clos.mbox = mbox;
......@@ -216,32 +208,34 @@ main (int argc, char **argv)
//FIXME: msgset operates on UIDs but there's no way to inform it about that.
switch (action)
{
case ARG_ADD:
case action_add:
if (!seq_list)
{
mu_error (_("--add requires at least one --sequence argument"));
return 1;
}
mu_list_foreach (seq_list, action_add, (void *) &clos);
mu_list_foreach (seq_list, do_add, (void *) &clos);
mh_global_save_state ();
break;
case ARG_DELETE:
case action_delete:
if (!seq_list)
{
mu_error (_("--delete requires at least one --sequence argument"));
return 1;
}
mu_list_foreach (seq_list, action_delete, (void *) &clos);
mu_list_foreach (seq_list, do_delete, (void *) &clos);
mh_global_save_state ();
break;
case ARG_LIST:
case action_list:
if (!seq_list)
list_all (mbox);
else
mu_list_foreach (seq_list, action_list, &clos);
mu_list_foreach (seq_list, do_list, &clos);
break;
default:
abort ();
}
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
......
......@@ -57,6 +57,7 @@
#include <mailutils/io.h>
#include <mailutils/property.h>
#include <mailutils/prog.h>
#include <mailutils/opool.h>
#include <mailutils/mh.h>
#include <mailutils/stdstream.h>
#include <mailutils/datetime.h>
......@@ -230,7 +231,7 @@ extern int mh_mailbox_cur_default;
void mh_init (void);
void mh_init2 (void);
void mh_read_profile (void);
int mh_read_formfile (char *name, char **pformat);
int mh_read_formfile (char const *name, char **pformat);
mu_message_t mh_file_to_message (const char *folder, const char *file_name);
mu_message_t mh_stream_to_message (mu_stream_t stream);
void mh_install (char *name, int automode);
......@@ -342,7 +343,7 @@ void mh_set_reply_regex (const char *str);
int mh_decode_2047 (char *text, char **decoded_text);
const char *mh_charset (const char *);
int mh_alias_read (char *name, int fail);
int mh_alias_read (char const *name, int fail);
int mh_alias_get (const char *name, mu_list_t *return_list);
int mh_alias_get_address (const char *name, mu_address_t *addr, int *incl);
int mh_alias_get_alias (const char *uname, mu_list_t *return_list);
......
......@@ -419,7 +419,7 @@ yywrap ()
/* Parses the named alias file */
int
mh_alias_read (char *name, int fail)
mh_alias_read (char const *name, int fail)
{
extern int yydebug;
char *p = getenv("ALI_YYDEBUG");
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999-2002, 2005-2007, 2009-2012, 2014-2016 Free
Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
/* Coexistence between GNU long options, traditional UNIX-style short
options and traditional MH long options. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <mh.h>
#include <string.h>
#include <mailutils/argcv.h>
#include "argp.h"
#ifdef MU_ALPHA_RELEASE
# include <git-describe.h>
#endif
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
struct mh_argp_data *data = state->input;
error_t ret = ARGP_ERR_UNKNOWN;
switch (key)
{
case ARGP_KEY_ARG:
if (arg[0] == '+')
ret = data->handler (ARG_FOLDER, arg + 1, state);
break;
default:
ret = data->handler (key, arg, state);
if (ret == 0)
{
if (key == ARGP_KEY_ERROR)
data->errind = state->next;
}
}
return ret;
}
static int
my_argp_parse (struct argp *argp, int argc, char **argv, int flags,
int *end_index, struct mh_argp_data *data)
{
int rc;
int f = 0;
int index = 0;
if (flags & ARGP_NO_ERRS)
{
while (argc > 0
&& (rc = argp_parse (argp, argc, argv, flags|f, end_index, data))
== EINVAL)
{
if (data->errind == -1)
break;
data->errind--;
if (f)
data->errind--;
argc -= data->errind;
argv += data->errind;
index += data->errind;
if (argc < 2 || memcmp (argv[1], "--", 2))
{
if (end_index)
*end_index = index + 1;
break;
}
f = ARGP_PARSE_ARGV0;
}
if (rc == 0 && end_index)
*end_index += index;
rc = 0;
}
else
rc = argp_parse (argp, argc, argv, flags, end_index, data);
return rc;
}
const char version_etc_copyright[] =
/* Do *not* mark this string for translation. %s is a copyright
symbol suitable for this locale, and %d is the copyright
year. */
"Copyright %s 2010 Free Software Foundation, inc.";
/* This is almost the same as mu_program_version_hook from muinit.c,
except for different formatting of the first line. MH uses:
progname (GNU Mailutils X.Y.Z)
where X.Y.Z stands for the version number. Emacs MH-E uses this
to determine Mailutils presence and its version number (see
lisp/mh-e/mh-e.el, function mh-variant-mu-mh-info). */
static void
mh_program_version_hook (FILE *stream, struct argp_state *state)
{
#ifdef GIT_DESCRIBE
fprintf (stream, "%s (%s %s) [%s]\n",
mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, GIT_DESCRIBE);
#else
fprintf (stream, "%s (%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. */
fprintf (stream, version_etc_copyright, _("(C)"));
fputs (_("\
\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\
"),
stream);
}
void
mh_argp_init ()
{
argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
argp_program_version_hook = mh_program_version_hook;
}
enum
{
OPT_DEBUG_LEVEL = 256,
OPT_DEBUG_LINE_INFO,
};
static struct argp_option mu_debug_argp_options[] =
{
{ "debug-level", OPT_DEBUG_LEVEL, N_("LEVEL"), 0,
N_("set Mailutils debugging level"), 0 },
{ "debug-line-info", OPT_DEBUG_LINE_INFO, NULL, 0,
N_("show source info with debugging messages"), 0 },
{ NULL }
};
static error_t
mu_debug_argp_parser (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case OPT_DEBUG_LEVEL:
mu_debug_parse_spec (arg);
break;
case OPT_DEBUG_LINE_INFO:
mu_debug_line_info = 1;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
struct argp mu_debug_argp = {
mu_debug_argp_options,
mu_debug_argp_parser,
};
struct argp_child mh_argp_children[] = {
{ &mu_debug_argp, 0, N_("Global debugging settings"), -2 },
{ NULL }
};
int
mh_argp_parse (int *pargc, char **pargv[],
int flags,
struct argp_option *option,
struct mh_option *mh_option,
char *argp_doc, char *doc,
argp_parser_t handler,
void *closure, int *pindex)
{
struct argp argp;
struct mh_argp_data data;
const char *val;
int index;
int extra = 0;
mu_set_program_name ((*pargv)[0]);
mh_init ();
mh_option_init (mh_option);
memset (&argp, 0, sizeof (argp));
argp.options = option;
argp.parser = parse_opt;
argp.args_doc = argp_doc;
argp.doc = doc;
argp.children = mh_argp_children;
data.mh_option = mh_option;
data.closure = closure;
data.handler = handler;
data.doc = argp_doc;
data.errind = -1;
val = mh_global_profile_get (mu_program_name, NULL);
if (val)
{
int argc;
char **argv;
int i, j;
struct mu_wordsplit ws;
if (mu_wordsplit (val, &ws, MU_WRDSF_DEFFLAGS))
{
mu_error (_("cannot split line `%s': %s"), val,
mu_wordsplit_strerror (&ws));
exit (1);
}
argc = *pargc + ws.ws_wordc;
argv = calloc (argc + 1, sizeof *argv);
if (!argv)
mh_err_memory (1);
i = 0;
argv[i++] = (*pargv)[0];
for (j = 0; j < ws.ws_wordc; i++, j++)
argv[i] = ws.ws_wordv[j];
for (j = 1; i < argc; i++, j++)
argv[i] = (*pargv)[j];
argv[i] = NULL;
ws.ws_wordc = 0;
mu_wordsplit_free (&ws);
mh_argv_preproc (argc, argv, &data);
my_argp_parse (&argp, argc, argv, flags, &index, &data);
extra = index < argc;
*pargc = argc;
*pargv = argv;
}
else
{
mh_argv_preproc (*pargc, *pargv, &data);
my_argp_parse (&argp, *pargc, *pargv, flags, &index, &data);
extra = index < *pargc;
}
if (pindex)
*pindex = index;
else if (extra)
{
mu_error (_("Extra arguments"));
exit (1);
}
mh_init2 ();
return 0;
}
void
mh_license (const char *name)
{
printf (_("This is %s\n\n"), name);
printf (
_(" GNU Mailutils is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
" the Free Software Foundation; either version 3 of the License, or\n"
" (at your option) any later version.\n"
"\n"
" GNU Mailutils is distributed in the hope that it will be useful,\n"
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
" GNU General Public License for more details.\n"
"\n"
" You should have received a copy of the GNU General Public License along\n"
" with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.\n"
"\n"
"\n"
));
exit (0);
}
......@@ -20,11 +20,10 @@
#include <mh.h>
#include <mh_format.h>
#include <mailutils/mime.h>
#include <mailutils/opool.h>
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <string.h>
#include <ctype.h>
#include "mbiter.h"
#include "mbchar.h"
#include "mbswidth.h"
......
......@@ -15,8 +15,6 @@
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
/* Parse traditional MH options. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
......@@ -24,197 +22,224 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mh_getopt.h>
#include "mh.h"
#include <mailutils/stream.h>
#include <mailutils/wordsplit.h>
#include <mailutils/io.h>
static int mh_optind = 1;
static char *mh_optarg;
static char *mh_optptr;
struct getopt_data
{
char *extra_doc;
};
void (*mh_help_hook) ();
static void
mh_extra_help_hook (struct mu_parseopt *po, mu_stream_t stream)
{
struct getopt_data *data = po->po_data;
mu_stream_printf (stream, "%s\n", _(data->extra_doc));
}
int
mh_getopt (int argc, char **argv, struct mh_option *mh_opt, const char *doc)
static void
augment_argv (int *pargc, char ***pargv)
{
struct mh_option *p;
int optlen;
int argc;
char **argv;
int i, j;
struct mu_wordsplit ws;
char const *val = mh_global_profile_get (mu_program_name, NULL);
if (mh_optind >= argc || argv[mh_optind] == NULL)
return EOF;
mh_optptr = argv[mh_optind];
if (!val)
return;
if (mh_optptr[0] == '+')
if (mu_wordsplit (val, &ws, MU_WRDSF_DEFFLAGS))
{
mh_optarg = mh_optptr + 1;
mh_optind++;
return '+';
mu_error (_("cannot split line `%s': %s"), val,
mu_wordsplit_strerror (&ws));
exit (1);
}
if (mh_optptr[0] != '-' || mh_optptr[1] == '-')
{
mh_optind++;
return 0;
}
argc = *pargc + ws.ws_wordc;
argv = calloc (argc + 1, sizeof *argv);
if (!argv)
mh_err_memory (1);
if (strcmp (mh_optptr, "-version") == 0)
mu_asprintf (&argv[mh_optind], "--version");
else
{
int negation = 0;
i = 0;
argv[i++] = (*pargv)[0];
for (j = 0; j < ws.ws_wordc; i++, j++)
argv[i] = ws.ws_wordv[j];
for (j = 1; i < argc; i++, j++)
argv[i] = (*pargv)[j];
argv[i] = NULL;
optlen = strlen (mh_optptr+1);
for (p = mh_opt; p->opt; p++)
{
if (p->match_len <= optlen
&& memcmp (mh_optptr+1, p->opt, optlen) == 0)
break;
if (p->flags == MH_OPT_BOOL
&& optlen > 2
&& memcmp (mh_optptr+1, "no", 2) == 0
&& strlen (p->opt) >= optlen-2
&& memcmp (mh_optptr+3, p->opt, optlen-2) == 0)
ws.ws_wordc = 0;
mu_wordsplit_free (&ws);
*pargc = argc;
*pargv = argv;
}
static void
process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po)
{
int i, j;
int argc = *pargc;
struct mu_option *opt;
/* Find folder option */
for (i = 0; ; i++)
{
negation = 1;
if (!po->po_optv[i])
return; /* Nothing to do */
if (MU_OPTION_IS_VALID_LONG_OPTION (po->po_optv[i])
&& strcmp (po->po_optv[i]->opt_long, "folder") == 0)
break;
}
}
opt = po->po_optv[i];
if (p->opt)
for (i = j = 0; i < argc; i++)
{
char *longopt = p->opt;
switch (p->flags)
if (argv[i][0] == '+')
{
case MH_OPT_BOOL:
mh_optarg = negation ? "no" : "yes";
mu_asprintf (&argv[mh_optind], "--%s=%s", longopt, mh_optarg);
break;
case MH_OPT_ARG:
mu_asprintf (&argv[mh_optind], "--%s", longopt);
mh_optarg = argv[++mh_optind];
break;
default:
mu_asprintf (&argv[mh_optind], "--%s", longopt);
mh_optarg = NULL;
}
mh_optind++;
return 1;
}
else if (!strcmp (mh_optptr+1, "help"))
{
mh_help (mh_opt, doc);
exit (1);
opt->opt_set (po, opt, argv[i] + 1);
}
else
mh_optind++;
argv[j++] = argv[i];
}
return '?';
argv[j] = NULL;
*pargc = j;
}
void
mh_argv_preproc (int argc, char **argv, struct mh_argp_data *data)
static void
set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
mh_optind = 1;
while (mh_getopt (argc, argv, data->mh_option, data->doc) != EOF)
;
mh_set_current_folder (arg);
}
static struct mu_option folder_option[] = {
{ "folder", 0, NULL, MU_OPTION_DEFAULT,
N_("set current folder"),
mu_c_string, NULL, set_folder },
MU_OPTION_END
};
void
mh_help (struct mh_option *mh_opt, const char *doc)
mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
int mhflags,
char *argdoc, char *progdoc, char *extradoc)
{
struct mh_option *p;
printf (_("Compatibility syntax:\n"));
printf (_("%s [switches] %s\n"), mu_program_name, doc);
printf (_(" switches are:\n"));
int argc = *pargc;
char **argv = *pargv;
struct mu_parseopt po;
struct mu_option *optv[3];
struct getopt_data getopt_data;
char const *args[2];
int flags = MU_PARSEOPT_SINGLE_DASH | MU_PARSEOPT_IMMEDIATE;
int i;
po.po_negation = "no";
flags |= MU_PARSEOPT_NEGATION;
if (argdoc)
{
args[0] = argdoc;
args[1] = NULL;
po.po_prog_args = args;
flags |= MU_PARSEOPT_PROG_ARGS;
}
if (progdoc)
{
po.po_prog_doc = progdoc;
flags |= MU_PARSEOPT_PROG_DOC;
}
for (p = mh_opt; p->opt; p++)
getopt_data.extra_doc = extradoc;
if (extradoc)
{
int len = strlen (p->opt);
printf (" -");
if (p->flags == MH_OPT_BOOL)
printf ("[no]");
if (len > p->match_len)
printf ("(%*.*s)%s",
(int) p->match_len, (int) p->match_len, p->opt,
p->opt + p->match_len);
else
printf ("%s", p->opt);
po.po_help_hook = mh_extra_help_hook;
flags |= MU_PARSEOPT_HELP_HOOK;
}
po.po_data = &getopt_data;
flags |= MU_PARSEOPT_DATA;
po.po_exit_error = 1;
flags |= MU_PARSEOPT_EXIT_ERROR;
po.po_package_name = PACKAGE_NAME;
flags |= MU_PARSEOPT_PACKAGE_NAME;
po.po_package_url = PACKAGE_URL;
flags |= MU_PARSEOPT_PACKAGE_URL;
po.po_bug_address = PACKAGE_BUGREPORT;
flags |= MU_PARSEOPT_BUG_ADDRESS;
//po.po_extra_info = gnu_general_help_url;
//flags |= MU_PARSEOPT_EXTRA_INFO;
mu_set_program_name (argv[0]);
mh_init ();
augment_argv (&argc, &argv);
if (p->flags == MH_OPT_ARG)
printf (" %s", p->arg);
printf ("\n");
i = 0;
if (mhflags & MH_GETOPT_DEFAULT_FOLDER)
optv[i++] = folder_option;
optv[i++] = options;
optv[i] = NULL;
if (mu_parseopt (&po, argc, argv, optv, flags))
exit (po.po_exit_error);
argc -= po.po_arg_start;
argv += po.po_arg_start;
process_folder_arg (&argc, argv, &po);
if (!argdoc && argc)
{
mu_error (_("Extra arguments"));
exit (1);
}
if (mh_help_hook)
mh_help_hook ();
printf (" -help\n");
printf (" -version\n");
printf (_("\nPlease use GNU long options instead.\n"
"Run %s --help for more info on these.\n"),
mu_program_name);
}
*pargc = argc;
*pargv = argv;
mh_init2 ();
}
static int
optcmp (const void *a, const void *b)
void
mh_opt_notimpl (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
struct mh_option const *opta = a, *optb = b;
return strcmp (opta->opt, optb->opt);
mu_error (_("option is not yet implemented: %s"), opt->opt_long);
exit (1);
}
void
mh_option_init (struct mh_option *opt)
mh_opt_notimpl_warning (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
size_t count, i;
/* Count number of elements and initialize minimum abbreviation
lengths to 1. */
for (count = 0; opt[count].opt; count++)
opt[count].match_len = 1;
/* Sort them alphabetically */
qsort (opt, count, sizeof (opt[0]), optcmp);
/* Determine minimum abbreviations */
for (i = 0; i < count; i++)
{
const char *sample = opt[i].opt;
size_t sample_len = strlen (sample);
size_t minlen = opt[i].match_len;
size_t j;
mu_error (_("ignoring not implemented option %s"), opt->opt_long);
}
for (j = i + 1; j < count; j++)
{
size_t len = strlen (opt[j].opt);
if (len >= minlen && memcmp (opt[j].opt, sample, minlen) == 0)
do
{
minlen++;
if (minlen <= strlen (opt[j].opt))
opt[j].match_len = minlen;
if (minlen == sample_len)
break;
}
while (len >= minlen && memcmp (opt[j].opt, sample, minlen) == 0);
else if (opt[j].opt[0] == sample[0])
opt[j].match_len = minlen;
else
break;
}
if (minlen <= sample_len)
opt[i].match_len = minlen;
}
void
mh_opt_clear_string (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
char **sptr = opt->opt_ptr;
free (*sptr);
*sptr = NULL;
}
void
mh_opt_notimpl (const char *name)
mh_opt_find_file (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
mu_error (_("option is not yet implemented: %s"), name);
exit (1);
mh_find_file (arg, opt->opt_ptr);
}
void
mh_opt_notimpl_warning (const char *name)
mh_opt_read_formfile (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
mu_error (_("ignoring not implemented option %s"), name);
mh_read_formfile (arg, opt->opt_ptr);
}
......
......@@ -16,198 +16,24 @@
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <mailutils/nls.h>
#include "argp.h"
#include "mailutils/libargp.h"
#include <mailutils/opt.h>
#define MH_OPT_BOOL 1
#define MH_OPT_ARG 2
#define MH_GETOPT_DEFAULT_FOLDER 0x1
struct mh_option
{
char *opt;
int flags;
char *arg;
size_t match_len;
};
struct mh_argp_data
{
struct mh_option *mh_option;
argp_parser_t handler;
int errind;
void *closure;
char *doc;
};
enum mh_arg {
ARG_ADD = 256,
ARG_AFTER,
ARG_ALIAS,
ARG_ALL,
ARG_AND,
ARG_ANNOTATE,
ARG_APOP,
ARG_AUDIT,
ARG_AUTO,
ARG_BEFORE,
ARG_BELL,
ARG_BUILD,
ARG_CC,
ARG_CFLAGS,
ARG_CHANGECUR,
ARG_CHARSET,
ARG_CHECK,
ARG_CHUNKSIZE,
ARG_CLEAR,
ARG_COMPAT,
ARG_COMPONENT,
ARG_COMPOSE,
ARG_CREATE,
ARG_DATE,
ARG_DATEFIELD,
ARG_DEBUG,
ARG_DELETE,
ARG_DRAFT,
ARG_DRAFTFOLDER,
ARG_DRAFTMESSAGE,
ARG_DRY_RUN,
ARG_DUMP,
ARG_EDITOR,
ARG_FAST,
ARG_FCC,
ARG_FILE,
ARG_FILTER,
ARG_FOLDER,
ARG_FORM,
ARG_FORMAT,
ARG_FORWARD,
ARG_FROM,
ARG_GROUP,
ARG_HEADER,
ARG_HOST,
ARG_INPLACE,
ARG_INTERACTIVE,
ARG_LANG,
ARG_LBRACE,
ARG_LENGTH,
ARG_LIMIT,
ARG_LINK,
ARG_LIST,
ARG_MIME,
ARG_MOREPROC,
ARG_MOVETO,
ARG_MSGID,
ARG_NOALIAS,
ARG_NOAPOP,
ARG_NOAUDIT,
ARG_NOAUTO,
ARG_NOBELL,
ARG_NOCC,
ARG_NOCHANGECUR,
ARG_NOCHECK,
ARG_NOCLEAR,
ARG_NOCOMPOSE,
ARG_NOCREATE,
ARG_NODATE,
ARG_NODATEFIELD,
ARG_NODRAFTFOLDER,
ARG_NOEDIT,
ARG_NOFAST,
ARG_NOFILTER,
ARG_NOFORMAT,
ARG_NOFORWARD,
ARG_NOHEADER,
ARG_NOHEADERS,
ARG_NOINPLACE,
ARG_NOINTERACTIVE,
ARG_NOLIMIT,
ARG_NOLIST,
ARG_NOMIME,
ARG_NOMOREPROC,
ARG_NOMSGID,
ARG_NONOTIFY,
ARG_NOPAUSE,
ARG_NOPUBLIC,
ARG_NOPUSH,
ARG_NOQUIET,
ARG_NOREALSIZE,
ARG_NORECURSIVE,
ARG_NOREVERSE,
ARG_NORMALIZE,
ARG_NOSERIALONLY,
ARG_NOSHOW,
ARG_NOSHOWPROC,
ARG_NOSTORE,
ARG_NOT,
ARG_NOTEXTFIELD,
ARG_NOTIFY,
ARG_NOTOTAL,
ARG_NOTRUNCATE,
ARG_NOUSE,
ARG_NOVERBOSE,
ARG_NOWATCH,
ARG_NOWHATNOWPROC,
ARG_NOZERO,
ARG_NUMFIELD,
ARG_OR,
ARG_PACK,
ARG_PART,
ARG_PATTERN,
ARG_PAUSE,
ARG_POP,
ARG_PRESERVE,
ARG_PRINT,
ARG_PROMPT,
ARG_PUBLIC,
ARG_PUSH,
ARG_QUERY,
ARG_QUIET,
ARG_RBRACE,
ARG_REALSIZE,
ARG_RECURSIVE,
ARG_REORDER,
ARG_REVERSE,
ARG_SCRIPT,
ARG_SEQUENCE,
ARG_SERIALONLY,
ARG_SHOW,
ARG_SHOWPROC,
ARG_SOURCE,
ARG_SPLIT,
ARG_STORE,
ARG_SUBJECT,
ARG_TEXT,
ARG_TEXTFIELD,
ARG_TO,
ARG_TOTAL,
ARG_TRUNCATE,
ARG_TYPE,
ARG_USE,
ARG_USER,
ARG_VERBOSE,
ARG_WATCH,
ARG_WHATNOWPROC,
ARG_WIDTH,
ARG_ZERO
};
extern void (*mh_help_hook) (void);
void mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
int flags,
char *argdoc, char *progdoc, char *extradoc);
void mh_option_init (struct mh_option *opt);
void mh_opt_notimpl (struct mu_parseopt *po, struct mu_option *opt,
char const *arg);
void mh_opt_notimpl_warning (struct mu_parseopt *po, struct mu_option *opt,
char const *arg);
void mh_opt_clear_string (struct mu_parseopt *po, struct mu_option *opt,
char const *arg);
void mh_argp_init (void);
void mh_argv_preproc (int argc, char **argv, struct mh_argp_data *data);
int mh_getopt (int argc, char **argv, struct mh_option *mh_opt, const char *doc);
int mh_argp_parse (int *argc, char **argv[],
int flags,
struct argp_option *option,
struct mh_option *mh_option,
char *argp_doc, char *doc,
argp_parser_t handler,
void *closure, int *index);
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_help (struct mh_option *mh_option, const char *doc);
void mh_license (const char *name);
void mh_opt_notimpl (const char *name);
void mh_opt_notimpl_warning (const char *name);
......
......@@ -59,7 +59,7 @@ mh_init2 ()
}
int
mh_read_formfile (char *name, char **pformat)
mh_read_formfile (char const *name, char **pformat)
{
FILE *fp;
struct stat st;
......
......@@ -21,48 +21,15 @@
#include <sys/stat.h>
#include <unistd.h>
static char doc[] = N_("GNU MH mhl")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH mhl");
static char args_doc[] = N_("[FILE [FILE...]]");
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{ "bell", ARG_BELL, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("ring the bell at the end of each output page") },
{"nobell", ARG_NOBELL, NULL, OPTION_HIDDEN, "" },
{ "clear", ARG_CLEAR, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("clear the screen after each page of output")},
{"noclear", ARG_NOCLEAR, NULL, OPTION_HIDDEN, "" },
{"form", ARG_FORM, N_("FILE"), 0,
N_("read format from given file")},
{"width", ARG_WIDTH, N_("NUMBER"), 0,
N_("set output width")},
{"length", ARG_LENGTH, N_("NUMBER"), 0,
N_("set output screen length")},
{"moreproc", ARG_MOREPROC, N_("PROG"), 0,
N_("use given PROG instead of the default") },
{"nomoreproc", ARG_NOMOREPROC, NULL, 0,
N_("disable use of moreproc program") },
{ NULL }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "bell", MH_OPT_BOOL },
{ "clear", MH_OPT_BOOL },
{ "form", MH_OPT_ARG, "formatfile"},
{ "width", MH_OPT_ARG, "number"},
{ "length", MH_OPT_ARG, "number"},
{ "moreproc", MH_OPT_ARG, "program"},
{ "nomoreproc" },
{ NULL }
};
static int bell_option;
static int clear_option;
static int interactive; /* Using interactive output */
static int mhl_fmt_flags; /* MHL format flags. Controlled by --bell
and --clear */
static int mhl_fmt_flags; /* MHL format flags. Controlled by -bell
and -clear */
static int length = 40; /* Length of output page */
static int width = 80; /* Width of output page */
static char *formfile = MHLIBDIR "/mhl.format";
......@@ -71,68 +38,30 @@ static int nomoreproc;
static mu_list_t format;
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 ARG_BELL:
if (is_true (arg))
mhl_fmt_flags |= MHL_BELL;
break;
case ARG_NOBELL:
mhl_fmt_flags &= ~MHL_BELL;
break;
case ARG_CLEAR:
if (is_true (arg))
mhl_fmt_flags |= MHL_CLEARSCREEN;
break;
case ARG_NOCLEAR:
mhl_fmt_flags &= ~MHL_CLEARSCREEN;
break;
case ARG_FORM:
mh_find_file (arg, &formfile);
break;
case ARG_WIDTH:
width = strtoul (arg, NULL, 0);
if (!width)
{
argp_error (state, _("invalid width"));
exit (1);
}
break;
case ARG_LENGTH:
length = strtoul (arg, NULL, 0);
if (!length)
{
argp_error (state, _("invalid length"));
exit (1);
}
break;
case ARG_MOREPROC:
moreproc = arg;
break;
case ARG_NOMOREPROC:
nomoreproc = 1;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "bell", 0, NULL, MU_OPTION_DEFAULT,
N_("ring the bell at the end of each output page"),
mu_c_bool, &bell_option },
{ "clear", 0, NULL, MU_OPTION_DEFAULT,
N_("clear the screen after each page of output"),
mu_c_bool, &clear_option },
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read format from given file"),
mu_c_string, &formfile, mh_opt_find_file },
{ "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set output width"),
mu_c_int, &width },
{ "length", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set output screen length"),
mu_c_int, &length },
{ "moreproc", 0, N_("PROG"), MU_OPTION_DEFAULT,
N_("use given PROG instead of the default"),
mu_c_string, &moreproc },
{ "nomoreproc", 0, NULL, MU_OPTION_DEFAULT,
N_("disable use of moreproc program"),
mu_c_bool, &nomoreproc },
MU_OPTION_END
};
static mu_stream_t
open_output ()
......@@ -205,23 +134,33 @@ list_message (char *name, mu_stream_t output)
int
main (int argc, char **argv)
{
int index;
mu_stream_t output;
interactive = isatty (1) && isatty (0);
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 (bell_option == -1)
/* use default */;
else if (bell_option)
mhl_fmt_flags |= MHL_BELL;
else
mhl_fmt_flags &= ~MHL_BELL;
if (clear_option == -1)
/* use default */;
else if (clear_option)
mhl_fmt_flags |= MHL_CLEARSCREEN;
else
mhl_fmt_flags &= ~MHL_CLEARSCREEN;
format = mhl_format_compile (formfile);
if (!format)
exit (1);
argc -= index;
argv += index;
if (argc == 0)
nomoreproc = 1;
......
......@@ -26,46 +26,9 @@
#include <time.h>
#include <mailutils/observer.h>
static char doc[] = N_("GNU MH scan")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char progdoc[] = N_("GNU MH scan");
static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to scan")},
{"clear", ARG_CLEAR, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("clear screen after displaying the list")},
{"noclear", ARG_NOCLEAR, NULL, OPTION_HIDDEN, ""},
{"form", ARG_FORM, N_("FILE"), 0,
N_("read format from given file")},
{"format", ARG_FORMAT, N_("FORMAT"), 0,
N_("use this format string")},
{"header", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("display header")},
{"width", ARG_WIDTH, N_("NUMBER"), 0,
N_("set output width")},
{"reverse", ARG_REVERSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("list messages in reverse order")},
{"noreverse", ARG_NOREVERSE, NULL, OPTION_HIDDEN, ""},
{"file", ARG_FILE, N_("FILE"), 0,
N_("[not yet implemented]")},
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "clear", MH_OPT_BOOL },
{ "form", MH_OPT_ARG, "formatfile" },
{ "format", MH_OPT_ARG, "string" },
{ "header", MH_OPT_BOOL },
{ "width", MH_OPT_ARG, "number" },
{ "reverse", MH_OPT_BOOL },
{ "file", MH_OPT_ARG, "file" },
{ NULL }
};
static int clear;
static char *format_str = mh_list_format;
......@@ -77,66 +40,41 @@ static mh_format_t format;
static mu_msgset_t msgset;
static int list_message (size_t num, mu_message_t msg, void *data);
void print_header (mu_mailbox_t mbox);
void clear_screen (void);
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
form_handler (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
{
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
case ARG_CLEAR:
clear = is_true(arg);
break;
case ARG_NOCLEAR:
clear = 0;
break;
case ARG_FORM:
if (mh_read_formfile (arg, &format_str))
exit (1);
break;
case ARG_FORMAT:
format_str = arg;
break;
case ARG_HEADER:
header = is_true(arg);
break;
case ARG_WIDTH:
width = strtoul (arg, NULL, 0);
if (!width)
{
argp_error (state, _("invalid width"));
exit (1);
}
break;
case ARG_REVERSE:
reverse = is_true(arg);
break;
case ARG_NOREVERSE:
reverse = 0;
break;
}
case ARG_FILE:
mh_opt_notimpl ("-file");
break;
static struct mu_option options[] = {
{ "clear", 0, NULL, MU_OPTION_DEFAULT,
N_("clear screen after displaying the list"),
mu_c_bool, &clear },
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read format from given file"),
mu_c_string, NULL, form_handler },
{ "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT,
N_("use this format string"),
mu_c_string, &format_str },
{ "header", 0, NULL, MU_OPTION_DEFAULT,
N_("display header"),
mu_c_bool, &header },
{ "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set output width"),
mu_c_int, &width },
{ "reverse", 0, NULL, MU_OPTION_DEFAULT,
N_("list messages in reverse order"),
mu_c_bool, &reverse },
{ "file", 0, N_("FILE"), MU_OPTION_HIDDEN,
N_("[not yet implemented]"),
mu_c_string, NULL, mh_opt_notimpl },
MU_OPTION_END
};
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static int list_message (size_t num, mu_message_t msg, void *data);
void print_header (mu_mailbox_t mbox);
void clear_screen (void);
/* Observable Action this is called at every message discover. */
static int
......@@ -161,7 +99,6 @@ action (mu_observer_t o, size_t type, void *data, void *action_data)
int
main (int argc, char **argv)
{
int index;
mu_mailbox_t mbox;
int status;
size_t total = 0;
......@@ -169,9 +106,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, options, MH_GETOPT_DEFAULT_FOLDER,
args_doc, progdoc, NULL);
if (mh_format_parse (format_str, &format))
{
......@@ -181,8 +117,6 @@ main (int argc, char **argv)
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
argc -= index;
argv += index;
if ((argc == 0 || strcmp (argv[0], "all") == 0) && !reverse)
{
/* Fast approach */
......
......@@ -90,7 +90,7 @@ Regards,
Sergey
])
burst +inbox --length=7 1 || exit $?
burst +inbox -length 7 1 || exit $?
grep -v ^X-Envelope- Mail/inbox/2
grep -v ^X-Envelope- Mail/inbox/3
grep -v ^X-Envelope- Mail/inbox/4
......@@ -140,7 +140,7 @@ With gently smiling jaws!
MH_CHECK([burst mime recursive],[burst03 burst-mime-recursive],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
burst +inbox --recursive 4 || exit $?
burst +inbox -recursive 4 || exit $?
grep -v ^X-Envelope- Mail/inbox/6
grep -v ^X-Envelope- Mail/inbox/7
grep -v ^X-Envelope- Mail/inbox/8
......
......@@ -99,13 +99,13 @@ Mail/inbox/4
Mail/inbox/5
])
MH_CHECK([folder --pack=N],[folder06 folder--pack=N],[
MH_CHECK([folder -pack=N],[folder06 folder-pack=N],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
for i in 1 2 3 4 5
do
mv Mail/inbox/$i Mail/inbox/${i}0
done
folder --pack=1 || exit $?
folder -pack=1 || exit $?
find Mail/inbox -not -name '.mu-prop' | sort
],
[0],
......