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.
Showing
24 changed files
with
832 additions
and
1908 deletions
... | @@ -47,6 +47,7 @@ struct mu_option | ... | @@ -47,6 +47,7 @@ struct mu_option |
47 | void *opt_ptr; /* Data pointer */ | 47 | void *opt_ptr; /* Data pointer */ |
48 | void (*opt_set) (struct mu_parseopt *, struct mu_option *, char const *); | 48 | void (*opt_set) (struct mu_parseopt *, struct mu_option *, char const *); |
49 | /* Function to set the option */ | 49 | /* Function to set the option */ |
50 | char const *opt_default;/* Default value */ | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | #define MU_OPTION_GROUP(text) { NULL, 0, NULL, 0, text } | 53 | #define MU_OPTION_GROUP(text) { NULL, 0, NULL, 0, text } | ... | ... |
... | @@ -189,6 +189,31 @@ find_short_option (struct mu_parseopt *po, int chr) | ... | @@ -189,6 +189,31 @@ find_short_option (struct mu_parseopt *po, int chr) |
189 | return NULL; | 189 | return NULL; |
190 | } | 190 | } |
191 | 191 | ||
192 | enum neg_match | ||
193 | { | ||
194 | neg_nomatch, | ||
195 | neg_match_inexact, | ||
196 | neg_match_exact | ||
197 | }; | ||
198 | |||
199 | static enum neg_match | ||
200 | negmatch (struct mu_parseopt *po, size_t i, char const *optstr, size_t optlen) | ||
201 | { | ||
202 | if (mu_option_possible_negation (po, po->po_optv[i])) | ||
203 | { | ||
204 | size_t neglen = strlen (po->po_negation); | ||
205 | size_t len = strlen (po->po_optv[i]->opt_long); | ||
206 | if (optlen <= neglen + len | ||
207 | && memcmp (optstr, po->po_negation, neglen) == 0 | ||
208 | && memcmp (optstr + neglen, po->po_optv[i]->opt_long, | ||
209 | optlen - neglen) == 0) | ||
210 | { | ||
211 | return (optlen == neglen + len) ? neg_match_exact : neg_match_inexact; | ||
212 | } | ||
213 | } | ||
214 | return neg_nomatch; | ||
215 | } | ||
216 | |||
192 | /* Find a descriptor of long option OPTSTR. If it has argument, return | 217 | /* Find a descriptor of long option OPTSTR. If it has argument, return |
193 | it in *ARGPTR. */ | 218 | it in *ARGPTR. */ |
194 | struct mu_option * | 219 | struct mu_option * |
... | @@ -200,14 +225,11 @@ find_long_option (struct mu_parseopt *po, char const *optstr, | ... | @@ -200,14 +225,11 @@ find_long_option (struct mu_parseopt *po, char const *optstr, |
200 | size_t i; | 225 | size_t i; |
201 | size_t optlen; /* Length of the option in optstr */ | 226 | size_t optlen; /* Length of the option in optstr */ |
202 | int found = 0; /* 1 if the match was found, 2 if option is ambiguous */ | 227 | int found = 0; /* 1 if the match was found, 2 if option is ambiguous */ |
203 | int neglen; /* Length of the negation prefix, if any */ | 228 | enum neg_match neg; /* 1 if a boolean option is negated */ |
204 | int neg = 0; /* 1 if a boolean option is negated */ | ||
205 | struct mu_option *ret_opt = NULL; | 229 | struct mu_option *ret_opt = NULL; |
206 | struct mu_option *used_opt; | 230 | struct mu_option *used_opt; |
207 | 231 | ||
208 | optlen = strcspn (optstr, "="); | 232 | optlen = strcspn (optstr, "="); |
209 | if (po->po_negation) | ||
210 | neglen = strlen (po->po_negation); | ||
211 | 233 | ||
212 | for (i = 0; i < po->po_optc; i++) | 234 | for (i = 0; i < po->po_optc; i++) |
213 | { | 235 | { |
... | @@ -215,14 +237,10 @@ find_long_option (struct mu_parseopt *po, char const *optstr, | ... | @@ -215,14 +237,10 @@ find_long_option (struct mu_parseopt *po, char const *optstr, |
215 | { | 237 | { |
216 | size_t len = strlen (po->po_optv[i]->opt_long); | 238 | size_t len = strlen (po->po_optv[i]->opt_long); |
217 | struct mu_option *opt = option_unalias (po, i); | 239 | struct mu_option *opt = option_unalias (po, i); |
218 | 240 | neg = neg_nomatch; | |
219 | if ((optlen <= len | 241 | if ((optlen <= len |
220 | && memcmp (po->po_optv[i]->opt_long, optstr, optlen) == 0) | 242 | && memcmp (po->po_optv[i]->opt_long, optstr, optlen) == 0) |
221 | || (neg = (mu_option_possible_negation (po, opt) | 243 | || (neg = negmatch (po, i, optstr, optlen))) |
222 | && optlen <= neglen + len | ||
223 | && memcmp (optstr, po->po_negation, neglen) == 0 | ||
224 | && memcmp (optstr + neglen, po->po_optv[i]->opt_long, | ||
225 | optlen - neglen) == 0))) | ||
226 | { | 244 | { |
227 | switch (found) | 245 | switch (found) |
228 | { | 246 | { |
... | @@ -230,7 +248,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr, | ... | @@ -230,7 +248,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr, |
230 | used_opt = po->po_optv[i]; | 248 | used_opt = po->po_optv[i]; |
231 | ret_opt = opt; | 249 | ret_opt = opt; |
232 | found++; | 250 | found++; |
233 | if (optlen == len || (neg && optlen == neglen + len)) | 251 | if (optlen == len || neg == neg_match_exact) |
234 | i = po->po_optc - 1; /* exact match: break the loop */ | 252 | i = po->po_optc - 1; /* exact match: break the loop */ |
235 | break; | 253 | break; |
236 | 254 | ||
... | @@ -247,6 +265,11 @@ find_long_option (struct mu_parseopt *po, char const *optstr, | ... | @@ -247,6 +265,11 @@ find_long_option (struct mu_parseopt *po, char const *optstr, |
247 | po->po_long_opt_start, | 265 | po->po_long_opt_start, |
248 | neg ? po->po_negation : "", | 266 | neg ? po->po_negation : "", |
249 | used_opt->opt_long); | 267 | used_opt->opt_long); |
268 | if (neg == neg_nomatch && negmatch (po, i, optstr, optlen)) | ||
269 | fprintf (stderr, "%s%s%s\n", | ||
270 | po->po_long_opt_start, | ||
271 | po->po_negation, | ||
272 | po->po_optv[i]->opt_long); | ||
250 | found++; | 273 | found++; |
251 | 274 | ||
252 | case 2: | 275 | case 2: |
... | @@ -254,6 +277,11 @@ find_long_option (struct mu_parseopt *po, char const *optstr, | ... | @@ -254,6 +277,11 @@ find_long_option (struct mu_parseopt *po, char const *optstr, |
254 | po->po_long_opt_start, | 277 | po->po_long_opt_start, |
255 | neg ? po->po_negation : "", | 278 | neg ? po->po_negation : "", |
256 | po->po_optv[i]->opt_long); | 279 | po->po_optv[i]->opt_long); |
280 | if (neg == neg_nomatch && negmatch (po, i, optstr, optlen)) | ||
281 | fprintf (stderr, "%s%s%s\n", | ||
282 | po->po_long_opt_start, | ||
283 | po->po_negation, | ||
284 | po->po_optv[i]->opt_long); | ||
257 | } | 285 | } |
258 | } | 286 | } |
259 | } | 287 | } |
... | @@ -719,7 +747,9 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, | ... | @@ -719,7 +747,9 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, |
719 | 747 | ||
720 | if (arg == NULL) | 748 | if (arg == NULL) |
721 | { | 749 | { |
722 | if (opt->opt_arg == NULL) | 750 | if (opt->opt_default) |
751 | arg = opt->opt_default; | ||
752 | else if (opt->opt_arg == NULL) | ||
723 | arg = "1"; | 753 | arg = "1"; |
724 | else | 754 | else |
725 | { | 755 | { |
... | @@ -737,7 +767,8 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, | ... | @@ -737,7 +767,8 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, |
737 | errtext = mu_strerror (rc); | 767 | errtext = mu_strerror (rc); |
738 | 768 | ||
739 | if (opt->opt_long) | 769 | if (opt->opt_long) |
740 | mu_parseopt_error (po, "--%s: %s", opt->opt_long, errtext); | 770 | mu_parseopt_error (po, "%s%s: %s", po->po_long_opt_start, |
771 | opt->opt_long, errtext); | ||
741 | else | 772 | else |
742 | mu_parseopt_error (po, "-%c: %s", opt->opt_short, errtext); | 773 | mu_parseopt_error (po, "-%c: %s", opt->opt_short, errtext); |
743 | free (errmsg); | 774 | free (errmsg); | ... | ... |
... | @@ -70,7 +70,6 @@ libmh_a_SOURCES= \ | ... | @@ -70,7 +70,6 @@ libmh_a_SOURCES= \ |
70 | mboxprop.c\ | 70 | mboxprop.c\ |
71 | mh_alias_gram.c\ | 71 | mh_alias_gram.c\ |
72 | mh_alias_lex.c\ | 72 | mh_alias_lex.c\ |
73 | mh_argp.c\ | ||
74 | mh_getopt.c\ | 73 | mh_getopt.c\ |
75 | mh_global.c\ | 74 | mh_global.c\ |
76 | mh_format.c\ | 75 | mh_format.c\ | ... | ... |
... | @@ -23,73 +23,41 @@ | ... | @@ -23,73 +23,41 @@ |
23 | #include <sys/ioctl.h> | 23 | #include <sys/ioctl.h> |
24 | #include <sys/stat.h> | 24 | #include <sys/stat.h> |
25 | 25 | ||
26 | static char doc[] = N_("GNU MH ali")"\v" | 26 | static char prog_doc[] = N_("GNU MH ali"); |
27 | N_("Use -help to obtain the list of traditional MH options."); | ||
28 | static char args_doc[] = N_("ALIAS [ALIAS...]"); | 27 | static char args_doc[] = N_("ALIAS [ALIAS...]"); |
29 | 28 | ||
30 | /* GNU options */ | ||
31 | static struct argp_option options[] = { | ||
32 | {"alias", ARG_ALIAS, N_("FILE"), 0, | ||
33 | N_("use the additional alias FILE")}, | ||
34 | {"noalias", ARG_NOALIAS, NULL, 0, | ||
35 | N_("do not read the system alias file") }, | ||
36 | {"list", ARG_LIST, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
37 | N_("list each address on a separate line") }, | ||
38 | {"normalize", ARG_NORMALIZE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
39 | N_("try to determine the official hostname for each address") }, | ||
40 | {"user", ARG_USER, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
41 | N_("list the aliases that expand to given addresses") }, | ||
42 | { 0 } | ||
43 | }; | ||
44 | |||
45 | /* Traditional MH options */ | ||
46 | struct mh_option mh_option[] = { | ||
47 | { "alias", MH_OPT_ARG, "aliasfile" }, | ||
48 | { "noalias", }, | ||
49 | { "list", MH_OPT_BOOL }, | ||
50 | { "normalize", MH_OPT_BOOL }, | ||
51 | { "user", MH_OPT_BOOL }, | ||
52 | { NULL } | ||
53 | }; | ||
54 | |||
55 | static int list_mode; | 29 | static int list_mode; |
56 | static int user_mode; | 30 | static int user_mode; |
57 | static int normalize_mode; | 31 | static int normalize_mode; |
58 | static int nolist_mode; | 32 | static int nolist_mode; |
59 | 33 | ||
60 | static error_t | 34 | static void |
61 | opt_handler (int key, char *arg, struct argp_state *state) | 35 | alias_handler (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
62 | { | 36 | { |
63 | switch (key) | ||
64 | { | ||
65 | case ARG_ALIAS: | ||
66 | mh_alias_read (arg, 1); | 37 | mh_alias_read (arg, 1); |
67 | break; | ||
68 | |||
69 | case ARG_NOALIAS: | ||
70 | nolist_mode = 1; | ||
71 | break; | ||
72 | |||
73 | case ARG_LIST: | ||
74 | list_mode = is_true (arg); | ||
75 | break; | ||
76 | |||
77 | case ARG_NORMALIZE: | ||
78 | normalize_mode = is_true (arg); | ||
79 | break; | ||
80 | |||
81 | case ARG_USER: | ||
82 | user_mode = is_true (arg); | ||
83 | break; | ||
84 | |||
85 | default: | ||
86 | return ARGP_ERR_UNKNOWN; | ||
87 | } | ||
88 | return 0; | ||
89 | } | 38 | } |
90 | 39 | ||
40 | static struct mu_option options[] = { | ||
41 | { "alias", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
42 | N_("use the additional alias FILE"), | ||
43 | mu_c_string, NULL, alias_handler }, | ||
44 | { "noalias", 0, NULL, 0, | ||
45 | N_("do not read the system alias file"), | ||
46 | mu_c_int, &nolist_mode, NULL, "1" }, | ||
47 | { "list", 0, NULL, MU_OPTION_DEFAULT, | ||
48 | N_("list each address on a separate line"), | ||
49 | mu_c_bool, &list_mode }, | ||
50 | { "normalize", 0, NULL, MU_OPTION_DEFAULT, | ||
51 | N_("try to determine the official hostname for each address"), | ||
52 | mu_c_bool, &normalize_mode }, | ||
53 | { "user", 0, NULL, MU_OPTION_DEFAULT, | ||
54 | N_("list the aliases that expand to given addresses"), | ||
55 | mu_c_bool, &user_mode }, | ||
56 | MU_OPTION_END | ||
57 | }; | ||
58 | |||
91 | static int | 59 | static int |
92 | getcols () | 60 | getcols (void) |
93 | { | 61 | { |
94 | struct winsize ws; | 62 | struct winsize ws; |
95 | 63 | ||
... | @@ -174,17 +142,10 @@ ali_print_name (char *name) | ... | @@ -174,17 +142,10 @@ ali_print_name (char *name) |
174 | int | 142 | int |
175 | main (int argc, char **argv) | 143 | main (int argc, char **argv) |
176 | { | 144 | { |
177 | int index; | ||
178 | |||
179 | /* Native Language Support */ | 145 | /* Native Language Support */ |
180 | MU_APP_INIT_NLS (); | 146 | MU_APP_INIT_NLS (); |
181 | 147 | ||
182 | mh_argp_init (); | 148 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
183 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | ||
184 | opt_handler, NULL, &index); | ||
185 | |||
186 | argc -= index; | ||
187 | argv += index; | ||
188 | 149 | ||
189 | if (!nolist_mode) | 150 | if (!nolist_mode) |
190 | mh_read_aliases (); | 151 | mh_read_aliases (); | ... | ... |
... | @@ -19,81 +19,29 @@ | ... | @@ -19,81 +19,29 @@ |
19 | 19 | ||
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | 21 | ||
22 | static char doc[] = N_("GNU MH anno")"\v" | 22 | static char prog_doc[] = N_("GNU MH anno"); |
23 | N_("Options marked with `*' are not yet implemented.\n\ | ||
24 | Use -help to obtain the list of traditional MH options."); | ||
25 | static char args_doc[] = N_("[MSGLIST]"); | 23 | static char args_doc[] = N_("[MSGLIST]"); |
26 | 24 | ||
27 | /* GNU options */ | 25 | //static int inplace; /* Annotate the message in place */ |
28 | static struct argp_option options[] = { | ||
29 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
30 | N_("specify folder to operate upon")}, | ||
31 | {"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
32 | N_("* annotate the message in place")}, | ||
33 | {"noinplace", ARG_NOINPLACE, NULL, OPTION_HIDDEN, "" }, | ||
34 | {"date", ARG_DATE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
35 | N_("add FIELD: date header") }, | ||
36 | {"nodate", ARG_NODATE, NULL, OPTION_HIDDEN, "" }, | ||
37 | {"component", ARG_COMPONENT, N_("FIELD"), 0, | ||
38 | N_("add this FIELD to the message header") }, | ||
39 | {"text", ARG_TEXT, N_("STRING"), 0, | ||
40 | N_("field value for the component") }, | ||
41 | { NULL } | ||
42 | }; | ||
43 | |||
44 | struct mh_option mh_option[] = { | ||
45 | { "inplace", MH_OPT_BOOL }, | ||
46 | { "date", MH_OPT_BOOL }, | ||
47 | { "component", MH_OPT_ARG, "field" }, | ||
48 | { "text", MH_OPT_ARG, "body" }, | ||
49 | { NULL } | ||
50 | }; | ||
51 | |||
52 | static int inplace; /* Annotate the message in place */ | ||
53 | static int anno_date = 1; /* Add date to the annotation */ | 26 | static int anno_date = 1; /* Add date to the annotation */ |
54 | static char *component; /* header field */ | 27 | static char *component; /* header field */ |
55 | static char *anno_text; /* header field value */ | 28 | static char *anno_text; /* header field value */ |
56 | 29 | ||
57 | static error_t | 30 | static struct mu_option options[] = { |
58 | opt_handler (int key, char *arg, struct argp_state *state) | 31 | { "inplace", 0, NULL, MU_OPTION_HIDDEN, |
59 | { | 32 | N_("annotate the message in place"), |
60 | switch (key) | 33 | mu_c_string, NULL, mh_opt_notimpl_warning }, |
61 | { | 34 | { "date", 0, NULL, MU_OPTION_DEFAULT, |
62 | case ARG_FOLDER: | 35 | N_("add FIELD: date header"), |
63 | mh_set_current_folder (arg); | 36 | mu_c_bool, &anno_date }, |
64 | break; | 37 | { "component", 0, N_("FIELD"), MU_OPTION_DEFAULT, |
65 | 38 | N_("add this FIELD to the message header"), | |
66 | case ARG_INPLACE: | 39 | mu_c_string, &component }, |
67 | mh_opt_notimpl_warning ("-inplace"); | 40 | { "text", 0, N_("STRING"), MU_OPTION_DEFAULT, |
68 | inplace = is_true (arg); | 41 | N_("field value for the component"), |
69 | break; | 42 | mu_c_string, &anno_text }, |
70 | 43 | MU_OPTION_END | |
71 | case ARG_NOINPLACE: | 44 | }; |
72 | mh_opt_notimpl_warning ("-noinplace"); | ||
73 | inplace = 0; | ||
74 | break; | ||
75 | |||
76 | case ARG_DATE: | ||
77 | anno_date = is_true (arg); | ||
78 | break; | ||
79 | |||
80 | case ARG_NODATE: | ||
81 | anno_date = 0; | ||
82 | break; | ||
83 | |||
84 | case ARG_COMPONENT: | ||
85 | component = arg; | ||
86 | break; | ||
87 | |||
88 | case ARG_TEXT: | ||
89 | mh_quote (arg, &anno_text); | ||
90 | break; | ||
91 | |||
92 | default: | ||
93 | return ARGP_ERR_UNKNOWN; | ||
94 | } | ||
95 | return 0; | ||
96 | } | ||
97 | 45 | ||
98 | int | 46 | int |
99 | anno (size_t n, mu_message_t msg, void *call_data) | 47 | anno (size_t n, mu_message_t msg, void *call_data) |
... | @@ -106,16 +54,20 @@ int | ... | @@ -106,16 +54,20 @@ int |
106 | main (int argc, char **argv) | 54 | main (int argc, char **argv) |
107 | { | 55 | { |
108 | int rc; | 56 | int rc; |
109 | int index; | ||
110 | mu_mailbox_t mbox; | 57 | mu_mailbox_t mbox; |
111 | mu_msgset_t msgset; | 58 | mu_msgset_t msgset; |
112 | size_t len; | 59 | size_t len; |
113 | 60 | ||
114 | MU_APP_INIT_NLS (); | 61 | MU_APP_INIT_NLS (); |
115 | 62 | ||
116 | mh_argp_init (); | 63 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
117 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 64 | args_doc, prog_doc, NULL); |
118 | opt_handler, NULL, &index); | 65 | if (anno_text) |
66 | { | ||
67 | char *arg = anno_text; | ||
68 | mh_quote (arg, &anno_text); | ||
69 | free (arg); | ||
70 | } | ||
119 | 71 | ||
120 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); | 72 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); |
121 | 73 | ||
... | @@ -152,9 +104,6 @@ main (int argc, char **argv) | ... | @@ -152,9 +104,6 @@ main (int argc, char **argv) |
152 | if (len > 0 && component[len-1] == ':') | 104 | if (len > 0 && component[len-1] == ':') |
153 | component[len-1] = 0; | 105 | component[len-1] = 0; |
154 | 106 | ||
155 | argc -= index; | ||
156 | argv += index; | ||
157 | |||
158 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); | 107 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); |
159 | rc = mu_msgset_foreach_message (msgset, anno, NULL); | 108 | rc = mu_msgset_foreach_message (msgset, anno, NULL); |
160 | if (rc) | 109 | if (rc) | ... | ... |
... | @@ -18,40 +18,9 @@ | ... | @@ -18,40 +18,9 @@ |
18 | 18 | ||
19 | #include <mh.h> | 19 | #include <mh.h> |
20 | 20 | ||
21 | static char doc[] = N_("GNU MH burst")"\v" | 21 | static char prog_doc[] = N_("GNU MH burst"); |
22 | N_("Options marked with `*' are not yet implemented.\n\ | ||
23 | Use -help to obtain the list of traditional MH options."); | ||
24 | static char args_doc[] = N_("[MSGLIST]"); | 22 | static char args_doc[] = N_("[MSGLIST]"); |
25 | 23 | ||
26 | /* GNU options */ | ||
27 | static struct argp_option options[] = { | ||
28 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
29 | N_("specify folder to operate upon")}, | ||
30 | {"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
31 | N_("replace the source message with the table of contents, insert extracted messages after it") }, | ||
32 | {"noinplace", ARG_NOINPLACE, 0, OPTION_HIDDEN, ""}, | ||
33 | {"quiet", ARG_QUIET, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
34 | N_("be quiet about the messages that are not in digest format") }, | ||
35 | {"noquiet", ARG_NOQUIET, 0, OPTION_HIDDEN, ""}, | ||
36 | {"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
37 | N_("verbosely list the actions taken") }, | ||
38 | {"noverbose", ARG_NOVERBOSE, 0, OPTION_HIDDEN, ""}, | ||
39 | {"recursive", ARG_RECURSIVE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
40 | N_("recursively expand MIME messages") }, | ||
41 | {"norecursive", ARG_NORECURSIVE, 0, OPTION_HIDDEN, ""}, | ||
42 | {"length", ARG_LENGTH, N_("NUMBER"), 0, | ||
43 | N_("set minimal length of digest encapsulation boundary (default 1)") }, | ||
44 | { NULL } | ||
45 | }; | ||
46 | |||
47 | /* Traditional MH options */ | ||
48 | struct mh_option mh_option[] = { | ||
49 | { "inplace", MH_OPT_BOOL }, | ||
50 | { "quiet", MH_OPT_BOOL }, | ||
51 | { "verbose", MH_OPT_BOOL }, | ||
52 | { NULL } | ||
53 | }; | ||
54 | |||
55 | /* Command line switches */ | 24 | /* Command line switches */ |
56 | int inplace; | 25 | int inplace; |
57 | int quiet; | 26 | int quiet; |
... | @@ -61,59 +30,24 @@ int eb_min_length = 1; /* Minimal length of encapsulation boundary */ | ... | @@ -61,59 +30,24 @@ int eb_min_length = 1; /* Minimal length of encapsulation boundary */ |
61 | 30 | ||
62 | #define VERBOSE(c) do { if (verbose) { printf c; putchar ('\n'); } } while (0) | 31 | #define VERBOSE(c) do { if (verbose) { printf c; putchar ('\n'); } } while (0) |
63 | 32 | ||
64 | static error_t | 33 | static struct mu_option options[] = { |
65 | opt_handler (int key, char *arg, struct argp_state *state) | 34 | { "inplace", 0, NULL, MU_OPTION_DEFAULT, |
66 | { | 35 | N_("replace the source message with the table of contents, insert extracted messages after it"), |
67 | switch (key) | 36 | mu_c_bool, &inplace }, |
68 | { | 37 | { "quiet", 0, NULL, MU_OPTION_DEFAULT, |
69 | case ARG_FOLDER: | 38 | N_("be quiet about the messages that are not in digest format"), |
70 | mh_set_current_folder (arg); | 39 | mu_c_bool, &quiet }, |
71 | break; | 40 | { "verbose", 0, NULL, MU_OPTION_DEFAULT, |
72 | 41 | N_("verbosely list the actions taken"), | |
73 | case ARG_INPLACE: | 42 | mu_c_bool, &verbose }, |
74 | inplace = is_true (arg); | 43 | { "recursive", 0, NULL, MU_OPTION_DEFAULT, |
75 | break; | 44 | N_("recursively expand MIME messages"), |
76 | 45 | mu_c_bool, &recursive }, | |
77 | case ARG_NOINPLACE: | 46 | { "length", 0, N_("NUM"), MU_OPTION_DEFAULT, |
78 | inplace = 0; | 47 | N_("set minimal length of digest encapsulation boundary (default 1)"), |
79 | break; | 48 | mu_c_int, &eb_min_length }, |
80 | 49 | MU_OPTION_END | |
81 | case ARG_LENGTH: | 50 | }; |
82 | eb_min_length = strtoul (arg, NULL, 0); | ||
83 | if (eb_min_length == 0) | ||
84 | eb_min_length = 1; | ||
85 | break; | ||
86 | |||
87 | case ARG_VERBOSE: | ||
88 | verbose = is_true (arg); | ||
89 | break; | ||
90 | |||
91 | case ARG_NOVERBOSE: | ||
92 | verbose = 0; | ||
93 | break; | ||
94 | |||
95 | case ARG_RECURSIVE: | ||
96 | recursive = is_true (arg); | ||
97 | break; | ||
98 | |||
99 | case ARG_NORECURSIVE: | ||
100 | recursive = 0; | ||
101 | break; | ||
102 | |||
103 | case ARG_QUIET: | ||
104 | quiet = is_true (arg); | ||
105 | break; | ||
106 | |||
107 | case ARG_NOQUIET: | ||
108 | quiet = 0; | ||
109 | break; | ||
110 | |||
111 | default: | ||
112 | return ARGP_ERR_UNKNOWN; | ||
113 | } | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | 51 | ||
118 | /* General-purpose data structures */ | 52 | /* General-purpose data structures */ |
119 | struct burst_map | 53 | struct burst_map |
... | @@ -713,7 +647,7 @@ finalize_inplace (size_t lastuid) | ... | @@ -713,7 +647,7 @@ finalize_inplace (size_t lastuid) |
713 | int | 647 | int |
714 | main (int argc, char **argv) | 648 | main (int argc, char **argv) |
715 | { | 649 | { |
716 | int index, rc; | 650 | int rc; |
717 | mu_mailbox_t mbox; | 651 | mu_mailbox_t mbox; |
718 | mu_msgset_t msgset; | 652 | mu_msgset_t msgset; |
719 | const char *tempfolder = mh_global_profile_get ("Temp-Folder", ".temp"); | 653 | const char *tempfolder = mh_global_profile_get ("Temp-Folder", ".temp"); |
... | @@ -721,12 +655,10 @@ main (int argc, char **argv) | ... | @@ -721,12 +655,10 @@ main (int argc, char **argv) |
721 | /* Native Language Support */ | 655 | /* Native Language Support */ |
722 | MU_APP_INIT_NLS (); | 656 | MU_APP_INIT_NLS (); |
723 | 657 | ||
724 | mh_argp_init (); | 658 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
725 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 659 | args_doc, prog_doc, NULL); |
726 | opt_handler, NULL, &index); | 660 | if (eb_min_length == 0) |
727 | 661 | eb_min_length = 1; | |
728 | argc -= index; | ||
729 | argv += index; | ||
730 | 662 | ||
731 | VERBOSE ((_("Opening folder `%s'"), mh_current_folder ())); | 663 | VERBOSE ((_("Opening folder `%s'"), mh_current_folder ())); |
732 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); | 664 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); | ... | ... |
... | @@ -21,143 +21,73 @@ | ... | @@ -21,143 +21,73 @@ |
21 | #include <sys/types.h> | 21 | #include <sys/types.h> |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | 23 | ||
24 | static char doc[] = N_("GNU MH comp")"\v" | 24 | static char prog_doc[] = N_("GNU MH comp"); |
25 | N_("Options marked with `*' are not yet implemented.\n" | ||
26 | "Use -help to obtain the list of traditional MH options."); | ||
27 | static char args_doc[] = N_("[MSG]"); | 25 | static char args_doc[] = N_("[MSG]"); |
28 | 26 | ||
29 | /* GNU options */ | ||
30 | static struct argp_option options[] = { | ||
31 | {"build", ARG_BUILD, 0, 0, | ||
32 | N_("build the draft and quit immediately.")}, | ||
33 | {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0, | ||
34 | N_("specify the folder for message drafts")}, | ||
35 | {"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0, | ||
36 | N_("undo the effect of the last --draftfolder option")}, | ||
37 | {"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0, | ||
38 | N_("invoke the draftmessage facility")}, | ||
39 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
40 | N_("specify folder to operate upon")}, | ||
41 | {"file", ARG_FILE, N_("FILE"), 0, | ||
42 | N_("use FILE as the message draft")}, | ||
43 | {"editor", ARG_EDITOR, N_("PROG"), 0, | ||
44 | N_("set the editor program to use")}, | ||
45 | {"noedit", ARG_NOEDIT, 0, 0, | ||
46 | N_("suppress the initial edit")}, | ||
47 | {"form", ARG_FORM, N_("FILE"), 0, | ||
48 | N_("read format from given file")}, | ||
49 | {"whatnowproc", ARG_WHATNOWPROC, N_("PROG"), 0, | ||
50 | N_("set the replacement for whatnow program")}, | ||
51 | {"nowhatnowproc", ARG_NOWHATNOWPROC, NULL, 0, | ||
52 | N_("don't run whatnowproc")}, | ||
53 | {"use", ARG_USE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
54 | N_("use draft file preserved after the last session") }, | ||
55 | {"nouse", ARG_NOUSE, NULL, OPTION_HIDDEN, ""}, | ||
56 | { 0 } | ||
57 | }; | ||
58 | |||
59 | /* Traditional MH options */ | ||
60 | struct mh_option mh_option[] = { | ||
61 | { "build" }, | ||
62 | { "file", MH_OPT_ARG, "draftfile" }, | ||
63 | { "form", MH_OPT_ARG, "formatfile" }, | ||
64 | { "draftfolder", MH_OPT_ARG, "folder" }, | ||
65 | { "nodraftfolder" }, | ||
66 | { "draftmessage" }, | ||
67 | { "editor", MH_OPT_ARG, "program" }, | ||
68 | { "noedit" }, | ||
69 | { "whatnowproc", MH_OPT_ARG, "program" }, | ||
70 | { "nowhatnowproc" }, | ||
71 | { "use" }, | ||
72 | { NULL } | ||
73 | }; | ||
74 | |||
75 | struct mh_whatnow_env wh_env = { 0 }; | 27 | struct mh_whatnow_env wh_env = { 0 }; |
76 | static int initial_edit = 1; | 28 | static int initial_edit = 1; |
77 | static const char *whatnowproc; | 29 | static const char *whatnowproc; |
78 | static int nowhatnowproc; | 30 | static int nowhatnowproc; |
79 | char *formfile; | 31 | char *formfile; |
80 | static int build_only = 0; /* --build flag */ | 32 | static int build_only = 0; /* -build flag */ |
81 | static int use_draft = 0; /* --use flag */ | 33 | static int use_draft = 0; /* -use flag */ |
82 | static char *draftmessage = "new"; | 34 | static char *draftmessage = "new"; |
83 | static const char *draftfolder = NULL; | 35 | static const char *draftfolder = NULL; |
84 | static int folder_set; /* Folder is set on the command line */ | 36 | static int folder_set; /* Folder is set on the command line */ |
85 | 37 | ||
86 | static error_t | 38 | static void |
87 | opt_handler (int key, char *arg, struct argp_state *state) | 39 | set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
88 | { | 40 | { |
89 | switch (key) | ||
90 | { | ||
91 | case ARGP_KEY_INIT: | ||
92 | draftfolder = mh_global_profile_get ("Draft-Folder", NULL); | ||
93 | whatnowproc = mh_global_profile_get ("whatnowproc", NULL); | ||
94 | break; | ||
95 | |||
96 | case ARG_BUILD: | ||
97 | build_only = 1; | ||
98 | break; | ||
99 | |||
100 | case ARG_DRAFTFOLDER: | ||
101 | draftfolder = arg; | ||
102 | break; | ||
103 | |||
104 | case ARG_EDITOR: | ||
105 | wh_env.editor = arg; | ||
106 | break; | ||
107 | |||
108 | case ARG_FOLDER: | ||
109 | mh_set_current_folder (arg); | 41 | mh_set_current_folder (arg); |
110 | folder_set = 1; | 42 | folder_set = 1; |
111 | break; | 43 | } |
112 | |||
113 | case ARG_FORM: | ||
114 | mh_find_file (arg, &formfile); | ||
115 | break; | ||
116 | |||
117 | case ARG_DRAFTMESSAGE: | ||
118 | draftmessage = arg; | ||
119 | break; | ||
120 | |||
121 | case ARG_USE: | ||
122 | use_draft = is_true (arg); | ||
123 | draftmessage = "cur"; | ||
124 | break; | ||
125 | |||
126 | case ARG_NOUSE: | ||
127 | use_draft = 0; | ||
128 | break; | ||
129 | 44 | ||
130 | case ARG_FILE: | 45 | static void |
46 | set_file (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
47 | { | ||
131 | wh_env.file = mh_expand_name (NULL, arg, NAME_ANY); | 48 | wh_env.file = mh_expand_name (NULL, arg, NAME_ANY); |
132 | break; | ||
133 | |||
134 | case ARG_NODRAFTFOLDER: | ||
135 | draftfolder = NULL; | ||
136 | break; | ||
137 | |||
138 | case ARG_NOEDIT: | ||
139 | initial_edit = 0; | ||
140 | break; | ||
141 | |||
142 | case ARG_WHATNOWPROC: | ||
143 | whatnowproc = arg; | ||
144 | break; | ||
145 | |||
146 | case ARG_NOWHATNOWPROC: | ||
147 | nowhatnowproc = 1; | ||
148 | break; | ||
149 | |||
150 | case ARGP_KEY_FINI: | ||
151 | if (!formfile) | ||
152 | mh_find_file ("components", &formfile); | ||
153 | break; | ||
154 | |||
155 | default: | ||
156 | return ARGP_ERR_UNKNOWN; | ||
157 | } | ||
158 | return 0; | ||
159 | } | 49 | } |
160 | 50 | ||
51 | static struct mu_option options[] = { | ||
52 | { "build", 0, NULL, MU_OPTION_DEFAULT, | ||
53 | N_("build the draft and quit immediately."), | ||
54 | mu_c_bool, &build_only }, | ||
55 | { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
56 | N_("specify the folder for message drafts"), | ||
57 | mu_c_string, &draftfolder }, | ||
58 | { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT, | ||
59 | N_("undo the effect of the last --draftfolder option"), | ||
60 | mu_c_string, &draftfolder, mh_opt_clear_string }, | ||
61 | { "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT, | ||
62 | N_("invoke the draftmessage facility"), | ||
63 | mu_c_string, &draftmessage }, | ||
64 | { "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
65 | N_("specify folder to operate upon"), | ||
66 | mu_c_string, NULL, set_folder }, | ||
67 | { "file", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
68 | N_("use FILE as the message draft"), | ||
69 | mu_c_string, NULL, set_file }, | ||
70 | { "editor", 0, N_("PROG"), MU_OPTION_DEFAULT, | ||
71 | N_("set the editor program to use"), | ||
72 | mu_c_string, &wh_env.editor }, | ||
73 | { "noedit", 0, NULL, MU_OPTION_DEFAULT, | ||
74 | N_("suppress the initial edit"), | ||
75 | mu_c_int, &initial_edit, NULL, "0" }, | ||
76 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
77 | N_("read format from given file"), | ||
78 | mu_c_string, &formfile, mh_opt_find_file }, | ||
79 | { "whatnowproc", 0, N_("PROG"), MU_OPTION_DEFAULT, | ||
80 | N_("set the replacement for whatnow program"), | ||
81 | mu_c_string, &whatnowproc }, | ||
82 | { "nowhatnowproc", 0, NULL, MU_OPTION_DEFAULT, | ||
83 | N_("don't run whatnowproc"), | ||
84 | mu_c_string, &nowhatnowproc, NULL, "1" }, | ||
85 | { "use", 0, NULL, MU_OPTION_DEFAULT, | ||
86 | N_("use draft file preserved after the last session"), | ||
87 | mu_c_bool, &use_draft }, | ||
88 | MU_OPTION_END | ||
89 | }; | ||
90 | |||
161 | /* Copy Nth message from mailbox MBOX to FILE. */ | 91 | /* Copy Nth message from mailbox MBOX to FILE. */ |
162 | int | 92 | int |
163 | copy_message (mu_mailbox_t mbox, size_t n, const char *file) | 93 | 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) | ... | @@ -201,14 +131,18 @@ copy_message (mu_mailbox_t mbox, size_t n, const char *file) |
201 | int | 131 | int |
202 | main (int argc, char **argv) | 132 | main (int argc, char **argv) |
203 | { | 133 | { |
204 | int index; | ||
205 | |||
206 | /* Native Language Support */ | 134 | /* Native Language Support */ |
207 | MU_APP_INIT_NLS (); | 135 | MU_APP_INIT_NLS (); |
208 | 136 | ||
209 | mh_argp_init (); | 137 | draftfolder = mh_global_profile_get ("Draft-Folder", NULL); |
210 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 138 | whatnowproc = mh_global_profile_get ("whatnowproc", NULL); |
211 | opt_handler, NULL, &index); | 139 | |
140 | mh_getopt (&argc, &argv, options, 0, | ||
141 | args_doc, prog_doc, NULL); | ||
142 | if (use_draft) | ||
143 | draftmessage = "cur"; | ||
144 | if (!formfile) | ||
145 | mh_find_file ("components", &formfile); | ||
212 | 146 | ||
213 | if (wh_env.file) | 147 | if (wh_env.file) |
214 | { | 148 | { |
... | @@ -226,14 +160,14 @@ main (int argc, char **argv) | ... | @@ -226,14 +160,14 @@ main (int argc, char **argv) |
226 | { | 160 | { |
227 | if (build_only || !draftfolder) | 161 | if (build_only || !draftfolder) |
228 | { | 162 | { |
229 | switch (argc - index) | 163 | switch (argc) |
230 | { | 164 | { |
231 | case 0: | 165 | case 0: |
232 | wh_env.file = mh_expand_name (NULL, "draft", 0); | 166 | wh_env.file = mh_expand_name (NULL, "draft", 0); |
233 | break; | 167 | break; |
234 | 168 | ||
235 | case 1: | 169 | case 1: |
236 | wh_env.file = mh_expand_name (NULL, argv[index], 0); | 170 | wh_env.file = mh_expand_name (NULL, argv[0], 0); |
237 | break; | 171 | break; |
238 | 172 | ||
239 | default: | 173 | default: |
... | @@ -245,7 +179,7 @@ main (int argc, char **argv) | ... | @@ -245,7 +179,7 @@ main (int argc, char **argv) |
245 | { | 179 | { |
246 | /* Comp accepts a `file', and it will, if given | 180 | /* Comp accepts a `file', and it will, if given |
247 | `-draftfolder +folder' treat this arguments as `msg'. */ | 181 | `-draftfolder +folder' treat this arguments as `msg'. */ |
248 | if (use_draft || index < argc) | 182 | if (use_draft || argc) |
249 | { | 183 | { |
250 | mu_msgset_t msgset; | 184 | mu_msgset_t msgset; |
251 | mu_mailbox_t mbox; | 185 | mu_mailbox_t mbox; |
... | @@ -253,7 +187,7 @@ main (int argc, char **argv) | ... | @@ -253,7 +187,7 @@ main (int argc, char **argv) |
253 | mbox = mh_open_folder (draftfolder, | 187 | mbox = mh_open_folder (draftfolder, |
254 | MU_STREAM_RDWR|MU_STREAM_CREAT); | 188 | MU_STREAM_RDWR|MU_STREAM_CREAT); |
255 | mh_msgset_parse (&msgset, mbox, | 189 | mh_msgset_parse (&msgset, mbox, |
256 | argc - index, argv + index, | 190 | argc, argv, |
257 | use_draft ? "cur" : "new"); | 191 | use_draft ? "cur" : "new"); |
258 | if (!mh_msgset_single_message (msgset)) | 192 | if (!mh_msgset_single_message (msgset)) |
259 | { | 193 | { |
... | @@ -271,13 +205,13 @@ main (int argc, char **argv) | ... | @@ -271,13 +205,13 @@ main (int argc, char **argv) |
271 | } | 205 | } |
272 | wh_env.draftfile = wh_env.file; | 206 | wh_env.draftfile = wh_env.file; |
273 | 207 | ||
274 | if (folder_set && index < argc) | 208 | if (folder_set && argc) |
275 | { | 209 | { |
276 | mu_msgset_t msgset; | 210 | mu_msgset_t msgset; |
277 | mu_mailbox_t mbox; | 211 | mu_mailbox_t mbox; |
278 | 212 | ||
279 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); | 213 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); |
280 | mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur"); | 214 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); |
281 | if (!mh_msgset_single_message (msgset)) | 215 | if (!mh_msgset_single_message (msgset)) |
282 | { | 216 | { |
283 | mu_error (_("only one message at a time!")); | 217 | mu_error (_("only one message at a time!")); |
... | @@ -304,7 +238,7 @@ main (int argc, char **argv) | ... | @@ -304,7 +238,7 @@ main (int argc, char **argv) |
304 | } | 238 | } |
305 | } | 239 | } |
306 | 240 | ||
307 | /* Exit immediately if --build is given */ | 241 | /* Exit immediately if -build is given */ |
308 | if (build_only || nowhatnowproc) | 242 | if (build_only || nowhatnowproc) |
309 | return 0; | 243 | return 0; |
310 | 244 | ... | ... |
... | @@ -19,37 +19,33 @@ | ... | @@ -19,37 +19,33 @@ |
19 | 19 | ||
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | 21 | ||
22 | static char doc[] = N_("GNU MH fmtcheck")"\v" | 22 | static char prog_doc[] = N_("GNU MH fmtcheck"); |
23 | N_("Use -help to obtain the list of traditional MH options."); | ||
24 | |||
25 | /* GNU options */ | ||
26 | static struct argp_option options[] = { | ||
27 | {"form", ARG_FORM, N_("FILE"), 0, | ||
28 | N_("read format from given file")}, | ||
29 | {"format", ARG_FORMAT, N_("FORMAT"), 0, | ||
30 | N_("use this format string")}, | ||
31 | {"dump", ARG_DUMP, NULL, 0, | ||
32 | N_("dump the listing of compiled format code")}, | ||
33 | { "debug", ARG_DEBUG, NULL, 0, | ||
34 | N_("enable parser debugging output"),}, | ||
35 | |||
36 | { NULL } | ||
37 | }; | ||
38 | |||
39 | /* Traditional MH options */ | ||
40 | struct mh_option mh_option[] = { | ||
41 | { "form", MH_OPT_ARG, "formatfile" }, | ||
42 | { "format", MH_OPT_ARG, "string" }, | ||
43 | { NULL } | ||
44 | }; | ||
45 | 23 | ||
46 | char *format_str; | 24 | char *format_str; |
47 | static mh_format_t format; | 25 | static mh_format_t format; |
48 | 26 | int dump_option; | |
49 | typedef int (*action_fp) (void); | 27 | int debug_option; |
28 | |||
29 | static struct mu_option options[] = { | ||
30 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
31 | N_("read format from given file"), | ||
32 | mu_c_string, &format_str, mh_opt_read_formfile }, | ||
33 | |||
34 | { "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT, | ||
35 | N_("use this format string"), | ||
36 | mu_c_string, &format_str }, | ||
37 | { "dump", 0, NULL, MU_OPTION_HIDDEN, | ||
38 | N_("dump the listing of compiled format code"), | ||
39 | mu_c_bool, &dump_option }, | ||
40 | { "debug", 0, NULL, MU_OPTION_DEFAULT, | ||
41 | N_("enable parser debugging output"), | ||
42 | mu_c_bool, &debug_option }, | ||
43 | |||
44 | MU_OPTION_END | ||
45 | }; | ||
50 | 46 | ||
51 | static int | 47 | static int |
52 | action_dump () | 48 | action_dump (void) |
53 | { | 49 | { |
54 | if (!format_str) | 50 | if (!format_str) |
55 | { | 51 | { |
... | @@ -60,49 +56,18 @@ action_dump () | ... | @@ -60,49 +56,18 @@ action_dump () |
60 | return 0; | 56 | return 0; |
61 | } | 57 | } |
62 | 58 | ||
63 | static action_fp action = action_dump; | ||
64 | |||
65 | static error_t | ||
66 | opt_handler (int key, char *arg, struct argp_state *state) | ||
67 | { | ||
68 | switch (key) | ||
69 | { | ||
70 | case ARG_FORM: | ||
71 | mh_read_formfile (arg, &format_str); | ||
72 | break; | ||
73 | |||
74 | case ARG_FORMAT: | ||
75 | format_str = arg; | ||
76 | break; | ||
77 | |||
78 | case ARG_DUMP: | ||
79 | action = action_dump; | ||
80 | break; | ||
81 | |||
82 | case ARG_DEBUG: | ||
83 | mh_format_debug (1); | ||
84 | break; | ||
85 | |||
86 | default: | ||
87 | return ARGP_ERR_UNKNOWN; | ||
88 | } | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | int | 59 | int |
93 | main (int argc, char **argv) | 60 | main (int argc, char **argv) |
94 | { | 61 | { |
95 | /* Native Language Support */ | 62 | /* Native Language Support */ |
96 | MU_APP_INIT_NLS (); | 63 | MU_APP_INIT_NLS (); |
97 | 64 | ||
98 | mh_argp_init (); | 65 | mh_getopt (&argc, &argv, options, 0, NULL, prog_doc, NULL); |
99 | mh_argp_parse (&argc, &argv, 0, options, mh_option, NULL, doc, | 66 | mh_format_debug (debug_option); |
100 | opt_handler, NULL, NULL); | ||
101 | |||
102 | if (format_str && mh_format_parse (format_str, &format)) | 67 | if (format_str && mh_format_parse (format_str, &format)) |
103 | { | 68 | { |
104 | mu_error (_("Bad format string")); | 69 | mu_error (_("Bad format string")); |
105 | exit (1); | 70 | exit (1); |
106 | } | 71 | } |
107 | return (*action) (); | 72 | return action_dump (); |
108 | } | 73 | } | ... | ... |
... | @@ -28,78 +28,16 @@ | ... | @@ -28,78 +28,16 @@ |
28 | 28 | ||
29 | #include <dirent.h> | 29 | #include <dirent.h> |
30 | 30 | ||
31 | static char doc[] = N_("GNU MH folder")"\v" | 31 | static char prog_doc[] = N_("GNU MH folder"); |
32 | N_("Use -help to obtain the list of traditional MH options."); | ||
33 | static char args_doc[] = N_("[ACTION] [MSG]"); | 32 | static char args_doc[] = N_("[ACTION] [MSG]"); |
34 | 33 | ||
35 | static struct argp_option options[] = { | 34 | typedef int (*folder_action) (void); |
36 | {N_("Actions are:"), 0, 0, OPTION_DOC, NULL, 0 }, | ||
37 | {"print", ARG_PRINT, NULL, 0, | ||
38 | N_("list the folders (default)"), 1 }, | ||
39 | {"list", ARG_LIST, NULL, 0, | ||
40 | N_("list the contents of the folder stack"), 1}, | ||
41 | {"pack", ARG_PACK, N_("NUMBER"), OPTION_ARG_OPTIONAL, | ||
42 | N_("remove holes in message numbering, begin numbering from NUMBER (default: first message number)"), 1}, | ||
43 | {"push", ARG_PUSH, N_("FOLDER"), OPTION_ARG_OPTIONAL, | ||
44 | N_("push the folder on the folder stack. If FOLDER is specified, it is pushed. " | ||
45 | "Otherwise, if a folder is given in the command line (via + or --folder), " | ||
46 | "it is pushed on stack. Otherwise, the current folder and the top of the folder " | ||
47 | "stack are exchanged"), 1}, | ||
48 | {"pop", ARG_POP, NULL, 0, | ||
49 | N_("pop the folder off the folder stack"), 1}, | ||
50 | |||
51 | {N_("Options are:"), 0, 0, OPTION_DOC, NULL, 2 }, | ||
52 | |||
53 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
54 | N_("specify folder to operate upon"), 3}, | ||
55 | {"all", ARG_ALL, NULL, 0, | ||
56 | N_("list all folders"), 3}, | ||
57 | {"create", ARG_CREATE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
58 | N_("create non-existing folders"), 3}, | ||
59 | {"nocreate", ARG_NOCREATE, NULL, OPTION_HIDDEN, ""}, | ||
60 | {"fast", ARG_FAST, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
61 | N_("list only the folder names"), 3}, | ||
62 | {"nofast", ARG_NOFAST, NULL, OPTION_HIDDEN, ""}, | ||
63 | {"header", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
64 | N_("print the header line"), 3}, | ||
65 | {"noheader", ARG_NOHEADER, NULL, OPTION_HIDDEN, ""}, | ||
66 | {"recurse",ARG_RECURSIVE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
67 | N_("scan folders recursively"), 3}, | ||
68 | {"norecurse", ARG_NORECURSIVE, NULL, OPTION_HIDDEN, ""}, | ||
69 | {"total", ARG_TOTAL, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
70 | N_("output the total statistics"), 3}, | ||
71 | {"nototal", ARG_NOTOTAL, NULL, OPTION_HIDDEN, ""}, | ||
72 | {"verbose", ARG_VERBOSE, NULL, 0, | ||
73 | N_("verbosely list actions taken"), 3}, | ||
74 | {"dry-run", ARG_DRY_RUN, NULL, 0, | ||
75 | N_("do nothing, print what would be done (with --pack)"), 3}, | ||
76 | |||
77 | {NULL}, | ||
78 | }; | ||
79 | |||
80 | /* Traditional MH options */ | ||
81 | struct mh_option mh_option[] = { | ||
82 | { "print" }, | ||
83 | { "list" }, | ||
84 | { "push" }, | ||
85 | { "pop" }, | ||
86 | { "all" }, | ||
87 | { "pack" }, | ||
88 | { "create", MH_OPT_BOOL }, | ||
89 | { "fast", MH_OPT_BOOL }, | ||
90 | { "header", MH_OPT_BOOL }, | ||
91 | { "recurse", MH_OPT_BOOL }, | ||
92 | { "total", MH_OPT_BOOL }, | ||
93 | { NULL } | ||
94 | }; | ||
95 | 35 | ||
96 | typedef int (*folder_action) (); | 36 | static int action_print (void); |
97 | 37 | static int action_list (void); | |
98 | static int action_print (); | 38 | static int action_push (void); |
99 | static int action_list (); | 39 | static int action_pop (void); |
100 | static int action_push (); | 40 | static int action_pack (void); |
101 | static int action_pop (); | ||
102 | static int action_pack (); | ||
103 | static folder_action action = action_print; | 41 | static folder_action action = action_print; |
104 | 42 | ||
105 | int show_all = 0; /* List all folders. Raised by --all switch */ | 43 | 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 */ | ... | @@ -121,110 +59,105 @@ const char *push_folder; /* Folder name to push on stack */ |
121 | const char *mh_seq_name; /* Name of the mh sequence file (defaults to | 59 | const char *mh_seq_name; /* Name of the mh sequence file (defaults to |
122 | .mh_sequences) */ | 60 | .mh_sequences) */ |
123 | int has_folder; /* Folder has been explicitely given */ | 61 | int has_folder; /* Folder has been explicitely given */ |
62 | int recurse_option = 0; | ||
124 | size_t max_depth = 1; /* Maximum recursion depth (0 means infinity) */ | 63 | size_t max_depth = 1; /* Maximum recursion depth (0 means infinity) */ |
125 | 64 | ||
126 | #define OPTION_IS_SET(opt) ((opt) == -1 ? show_all : opt) | 65 | #define OPTION_IS_SET(opt) ((opt) == -1 ? show_all : opt) |
127 | 66 | ||
128 | static int | 67 | void |
129 | opt_handler (int key, char *arg, struct argp_state *state) | 68 | set_action (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
130 | { | 69 | { |
131 | switch (key) | 70 | if (strcmp (opt->opt_long, "print") == 0) |
71 | action = action_print; | ||
72 | else if (strcmp (opt->opt_long, "pack") == 0) | ||
132 | { | 73 | { |
133 | case ARG_DRY_RUN: | ||
134 | dry_run++; | ||
135 | break; | ||
136 | |||
137 | case ARG_PACK: | ||
138 | action = action_pack; | 74 | action = action_pack; |
139 | if (arg) | 75 | if (arg) |
140 | { | 76 | { |
141 | char *p; | 77 | if (mu_str_to_c (arg, mu_c_size, &pack_start, NULL)) |
142 | pack_start = strtoul (arg, &p, 10); | 78 | { |
143 | if (*p) | 79 | mu_parseopt_error (po, _("%s: invalid number"), arg); |
144 | argp_error (state, _("invalid number")); | 80 | exit (po->po_exit_error); |
145 | } | 81 | } |
146 | break; | 82 | } |
147 | 83 | } | |
148 | case ARG_PRINT: | 84 | else if (strcmp (opt->opt_long, "list") == 0) |
149 | action = action_print; | ||
150 | break; | ||
151 | |||
152 | case ARG_LIST: | ||
153 | action = action_list; | 85 | action = action_list; |
154 | break; | 86 | else if (strcmp (opt->opt_long, "push") == 0) |
155 | 87 | { | |
156 | case ARG_PUSH: | ||
157 | action = action_push; | 88 | action = action_push; |
158 | if (arg) | 89 | if (arg) |
159 | { | 90 | { |
160 | push_folder = mh_current_folder (); | 91 | push_folder = mh_current_folder (); |
161 | mh_set_current_folder (arg); | 92 | mh_set_current_folder (arg); |
162 | } | 93 | } |
163 | break; | 94 | } |
164 | 95 | else if (strcmp (opt->opt_long, "pop") == 0) | |
165 | case ARG_POP: | ||
166 | action = action_pop; | 96 | action = action_pop; |
167 | break; | 97 | else |
168 | 98 | abort (); | |
169 | case ARG_ALL: | 99 | } |
170 | show_all = 1; | ||
171 | break; | ||
172 | |||
173 | case ARG_CREATE: | ||
174 | create_flag = is_true (arg); | ||
175 | break; | ||
176 | |||
177 | case ARG_NOCREATE: | ||
178 | create_flag = 0; | ||
179 | |||
180 | case ARG_FAST: | ||
181 | fast_mode = is_true (arg); | ||
182 | break; | ||
183 | |||
184 | case ARG_NOFAST: | ||
185 | fast_mode = 0; | ||
186 | break; | ||
187 | |||
188 | case ARG_HEADER: | ||
189 | print_header = is_true (arg); | ||
190 | break; | ||
191 | |||
192 | case ARG_NOHEADER: | ||
193 | print_header = 0; | ||
194 | break; | ||
195 | |||
196 | case ARG_RECURSIVE: | ||
197 | max_depth = is_true (arg) ? 0 : 1; | ||
198 | break; | ||
199 | |||
200 | case ARG_NORECURSIVE: | ||
201 | max_depth = 0; | ||
202 | break; | ||
203 | |||
204 | case ARG_TOTAL: | ||
205 | print_total = is_true (arg); | ||
206 | break; | ||
207 | |||
208 | case ARG_NOTOTAL: | ||
209 | print_total = 0; | ||
210 | break; | ||
211 | 100 | ||
212 | case ARG_FOLDER: | 101 | void |
102 | set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
103 | { | ||
213 | has_folder = 1; | 104 | has_folder = 1; |
214 | push_folder = mh_current_folder (); | 105 | push_folder = mh_current_folder (); |
215 | mh_set_current_folder (arg); | 106 | mh_set_current_folder (arg); |
216 | break; | ||
217 | |||
218 | case ARG_VERBOSE: | ||
219 | verbose++; | ||
220 | break; | ||
221 | |||
222 | default: | ||
223 | return ARGP_ERR_UNKNOWN; | ||
224 | } | ||
225 | return 0; | ||
226 | } | 107 | } |
227 | 108 | ||
109 | static struct mu_option options[] = { | ||
110 | MU_OPTION_GROUP (N_("Actions are:")), | ||
111 | { "print", 0, NULL, MU_OPTION_DEFAULT, | ||
112 | N_("list the folders (default)"), | ||
113 | mu_c_string, NULL, set_action }, | ||
114 | { "list", 0, NULL, MU_OPTION_DEFAULT, | ||
115 | N_("list the contents of the folder stack"), | ||
116 | mu_c_string, NULL, set_action }, | ||
117 | { "pack", 0, N_("NUMBER"), MU_OPTION_ARG_OPTIONAL, | ||
118 | N_("remove holes in message numbering, begin numbering from NUMBER (default: first message number)"), | ||
119 | mu_c_string, NULL, set_action }, | ||
120 | { "push", 0, N_("FOLDER"), MU_OPTION_ARG_OPTIONAL, | ||
121 | N_("push the folder on the folder stack. If FOLDER is specified, it is pushed. " | ||
122 | "Otherwise, if a folder is given in the command line (via + or --folder), " | ||
123 | "it is pushed on stack. Otherwise, the current folder and the top of the folder " | ||
124 | "stack are exchanged"), | ||
125 | mu_c_string, NULL, set_action }, | ||
126 | { "pop", 0, NULL, MU_OPTION_DEFAULT, | ||
127 | N_("pop the folder off the folder stack"), | ||
128 | mu_c_string, NULL, set_action }, | ||
129 | |||
130 | MU_OPTION_GROUP (N_("Options are:")), | ||
131 | |||
132 | { "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
133 | N_("specify folder to operate upon"), | ||
134 | mu_c_string, NULL, set_folder }, | ||
135 | { "all", 0, NULL, MU_OPTION_DEFAULT, | ||
136 | N_("list all folders"), | ||
137 | mu_c_bool, &show_all }, | ||
138 | { "create", 0, NULL, MU_OPTION_DEFAULT, | ||
139 | N_("create non-existing folders"), | ||
140 | mu_c_bool, &create_flag }, | ||
141 | { "fast", 0, NULL, MU_OPTION_DEFAULT, | ||
142 | N_("list only the folder names"), | ||
143 | mu_c_bool, &fast_mode }, | ||
144 | { "header", 0, NULL, MU_OPTION_DEFAULT, | ||
145 | N_("print the header line"), | ||
146 | mu_c_bool, &print_header }, | ||
147 | { "recurse",0, NULL, MU_OPTION_DEFAULT, | ||
148 | N_("scan folders recursively"), | ||
149 | mu_c_bool, &recurse_option }, | ||
150 | { "total", 0, NULL, MU_OPTION_DEFAULT, | ||
151 | N_("output the total statistics"), | ||
152 | mu_c_bool, &print_total }, | ||
153 | { "verbose", 0, NULL, MU_OPTION_DEFAULT, | ||
154 | N_("verbosely list actions taken"), | ||
155 | mu_c_bool, &verbose }, | ||
156 | { "dry-run", 0, NULL, MU_OPTION_DEFAULT, | ||
157 | N_("do nothing, print what would be done (with --pack)"), | ||
158 | mu_c_bool, &dry_run }, | ||
159 | MU_OPTION_END | ||
160 | }; | ||
228 | 161 | ||
229 | /* ************************************************************* */ | 162 | /* ************************************************************* */ |
230 | /* Printing */ | 163 | /* Printing */ |
... | @@ -430,19 +363,19 @@ _folder_name_printer (void *item, void *data) | ... | @@ -430,19 +363,19 @@ _folder_name_printer (void *item, void *data) |
430 | } | 363 | } |
431 | 364 | ||
432 | static void | 365 | static void |
433 | print_all () | 366 | print_all (void) |
434 | { | 367 | { |
435 | mu_list_foreach (folder_info_list, _folder_info_printer, NULL); | 368 | mu_list_foreach (folder_info_list, _folder_info_printer, NULL); |
436 | } | 369 | } |
437 | 370 | ||
438 | static void | 371 | static void |
439 | print_fast () | 372 | print_fast (void) |
440 | { | 373 | { |
441 | mu_list_foreach (folder_info_list, _folder_name_printer, NULL); | 374 | mu_list_foreach (folder_info_list, _folder_name_printer, NULL); |
442 | } | 375 | } |
443 | 376 | ||
444 | static int | 377 | static int |
445 | action_print () | 378 | action_print (void) |
446 | { | 379 | { |
447 | const char *folder_dir = mu_folder_directory (); | 380 | const char *folder_dir = mu_folder_directory (); |
448 | mh_seq_name = mh_global_profile_get ("mh-sequences", MH_SEQUENCES_FILE); | 381 | mh_seq_name = mh_global_profile_get ("mh-sequences", MH_SEQUENCES_FILE); |
... | @@ -502,7 +435,7 @@ action_print () | ... | @@ -502,7 +435,7 @@ action_print () |
502 | /* Listing */ | 435 | /* Listing */ |
503 | 436 | ||
504 | static int | 437 | static int |
505 | action_list () | 438 | action_list (void) |
506 | { | 439 | { |
507 | const char *stack = mh_global_context_get ("Folder-Stack", NULL); | 440 | const char *stack = mh_global_context_get ("Folder-Stack", NULL); |
508 | 441 | ||
... | @@ -598,7 +531,7 @@ pop_val (size_t *pc, char ***pv) | ... | @@ -598,7 +531,7 @@ pop_val (size_t *pc, char ***pv) |
598 | } | 531 | } |
599 | 532 | ||
600 | static int | 533 | static int |
601 | action_push () | 534 | action_push (void) |
602 | { | 535 | { |
603 | size_t c; | 536 | size_t c; |
604 | char **v; | 537 | char **v; |
... | @@ -623,7 +556,7 @@ action_push () | ... | @@ -623,7 +556,7 @@ action_push () |
623 | } | 556 | } |
624 | 557 | ||
625 | static int | 558 | static int |
626 | action_pop () | 559 | action_pop (void) |
627 | { | 560 | { |
628 | size_t c; | 561 | size_t c; |
629 | char **v; | 562 | char **v; |
... | @@ -849,7 +782,7 @@ fixup_private (const char *name, const char *value, void *data) | ... | @@ -849,7 +782,7 @@ fixup_private (const char *name, const char *value, void *data) |
849 | } | 782 | } |
850 | 783 | ||
851 | int | 784 | int |
852 | action_pack () | 785 | action_pack (void) |
853 | { | 786 | { |
854 | const char *folder_dir = mh_expand_name (NULL, mh_current_folder (), | 787 | const char *folder_dir = mh_expand_name (NULL, mh_current_folder (), |
855 | NAME_ANY); | 788 | NAME_ANY); |
... | @@ -959,9 +892,9 @@ main (int argc, char **argv) | ... | @@ -959,9 +892,9 @@ main (int argc, char **argv) |
959 | /* Native Language Support */ | 892 | /* Native Language Support */ |
960 | MU_APP_INIT_NLS (); | 893 | MU_APP_INIT_NLS (); |
961 | 894 | ||
962 | mh_argp_init (); | 895 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); |
963 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 896 | if (recurse_option) |
964 | opt_handler, NULL, &index); | 897 | max_depth = 0; |
965 | 898 | ||
966 | /* If folder is invoked by a name ending with "s" (e.g., folders), | 899 | /* If folder is invoked by a name ending with "s" (e.g., folders), |
967 | `-all' is assumed */ | 900 | `-all' is assumed */ | ... | ... |
... | @@ -19,79 +19,9 @@ | ... | @@ -19,79 +19,9 @@ |
19 | 19 | ||
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | 21 | ||
22 | static char doc[] = N_("GNU MH forw")"\v" | 22 | static char prog_doc[] = N_("GNU MH forw"); |
23 | N_("Options marked with `*' are not yet implemented.\n\ | ||
24 | Use -help to obtain the list of traditional MH options."); | ||
25 | static char args_doc[] = N_("[MSGLIST]"); | 23 | static char args_doc[] = N_("[MSGLIST]"); |
26 | 24 | ||
27 | /* GNU options */ | ||
28 | static struct argp_option options[] = { | ||
29 | {"annotate", ARG_ANNOTATE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
30 | N_("add Forwarded: header to each forwarded message")}, | ||
31 | {"build", ARG_BUILD, 0, 0, | ||
32 | N_("build the draft and quit immediately")}, | ||
33 | {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0, | ||
34 | N_("specify the folder for message drafts")}, | ||
35 | {"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0, | ||
36 | N_("undo the effect of the last --draftfolder option")}, | ||
37 | {"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0, | ||
38 | N_("invoke the draftmessage facility")}, | ||
39 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
40 | N_("specify folder to operate upon")}, | ||
41 | {"editor", ARG_EDITOR, N_("PROG"), 0, | ||
42 | N_("set the editor program to use")}, | ||
43 | {"noedit", ARG_NOEDIT, 0, 0, | ||
44 | N_("suppress the initial edit")}, | ||
45 | {"file", ARG_FILE, N_("FILE"), 0, | ||
46 | N_("read message from FILE")}, | ||
47 | {"format", ARG_FORMAT, N_("BOOL"), 0, | ||
48 | N_("format messages")}, | ||
49 | {"noformat", ARG_NOFORMAT, NULL, 0, | ||
50 | N_("undo the effect of the last --format option") }, | ||
51 | {"form", ARG_FORM, N_("FILE"), 0, | ||
52 | N_("read format from given file")}, | ||
53 | {"filter", ARG_FILTER, N_("FILE"), 0, | ||
54 | N_("use filter FILE to preprocess the body of the message") }, | ||
55 | {"nofilter", ARG_NOFILTER, NULL, 0, | ||
56 | N_("undo the effect of the last --filter option") }, | ||
57 | {"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
58 | N_("* annotate the message in place")}, | ||
59 | {"noinplace", ARG_NOINPLACE, 0, OPTION_HIDDEN, "" }, | ||
60 | {"mime", ARG_MIME, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
61 | N_("use MIME encapsulation") }, | ||
62 | {"nomime", ARG_NOMIME, NULL, OPTION_HIDDEN, "" }, | ||
63 | {"width", ARG_WIDTH, N_("NUMBER"), 0, N_("Set output width")}, | ||
64 | {"whatnowproc", ARG_WHATNOWPROC, N_("PROG"), 0, | ||
65 | N_("set the replacement for whatnow program")}, | ||
66 | {"nowhatnowproc", ARG_NOWHATNOWPROC, NULL, 0, | ||
67 | N_("don't run whatnowproc")}, | ||
68 | {"use", ARG_USE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
69 | N_("use draft file preserved after the last session") }, | ||
70 | {"nouse", ARG_NOUSE, N_("BOOL"), OPTION_HIDDEN, "" }, | ||
71 | |||
72 | {NULL}, | ||
73 | }; | ||
74 | |||
75 | /* Traditional MH options */ | ||
76 | struct mh_option mh_option[] = { | ||
77 | { "annotate", MH_OPT_BOOL }, | ||
78 | { "build" }, | ||
79 | { "file", MH_OPT_ARG, "msgfile" }, | ||
80 | { "form", MH_OPT_ARG, "formatfile" }, | ||
81 | { "format", MH_OPT_BOOL }, | ||
82 | { "draftfolder", MH_OPT_ARG, "folder" }, | ||
83 | { "nodraftfolder" }, | ||
84 | { "draftmessage" }, | ||
85 | { "editor", MH_OPT_ARG, "program" }, | ||
86 | { "noedit" }, | ||
87 | { "filter", MH_OPT_ARG, "program" }, | ||
88 | { "inplace", MH_OPT_BOOL }, | ||
89 | { "whatnowproc", MH_OPT_ARG, "program" }, | ||
90 | { "nowhatnowproc" }, | ||
91 | { "mime", MH_OPT_BOOL }, | ||
92 | { NULL } | ||
93 | }; | ||
94 | |||
95 | enum encap_type | 25 | enum encap_type |
96 | { | 26 | { |
97 | encap_clear, | 27 | encap_clear, |
... | @@ -120,123 +50,99 @@ static char *input_file; /* input file name (--file option) */ | ... | @@ -120,123 +50,99 @@ static char *input_file; /* input file name (--file option) */ |
120 | static mu_msgset_t msgset; | 50 | static mu_msgset_t msgset; |
121 | static mu_mailbox_t mbox; | 51 | static mu_mailbox_t mbox; |
122 | 52 | ||
123 | static int | 53 | static void |
124 | opt_handler (int key, char *arg, struct argp_state *state) | 54 | set_filter (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
125 | { | 55 | { |
126 | switch (key) | 56 | mh_find_file (arg, &mhl_filter_file); |
127 | { | 57 | encap = encap_mhl; |
128 | case ARGP_KEY_INIT: | 58 | } |
129 | draftfolder = mh_global_profile_get ("Draft-Folder", NULL); | ||
130 | whatnowproc = mh_global_profile_get ("whatnowproc", NULL); | ||
131 | break; | ||
132 | |||
133 | case ARG_ANNOTATE: | ||
134 | annotate = is_true (arg); | ||
135 | break; | ||
136 | |||
137 | case ARG_BUILD: | ||
138 | build_only = 1; | ||
139 | break; | ||
140 | |||
141 | case ARG_FILE: | ||
142 | input_file = arg; | ||
143 | break; | ||
144 | |||
145 | case ARG_DRAFTFOLDER: | ||
146 | draftfolder = arg; | ||
147 | break; | ||
148 | |||
149 | case ARG_NODRAFTFOLDER: | ||
150 | draftfolder = NULL; | ||
151 | break; | ||
152 | |||
153 | case ARG_DRAFTMESSAGE: | ||
154 | draftmessage = arg; | ||
155 | break; | ||
156 | |||
157 | case ARG_USE: | ||
158 | use_draft = is_true (arg); | ||
159 | break; | ||
160 | |||
161 | case ARG_NOUSE: | ||
162 | use_draft = 0; | ||
163 | break; | ||
164 | |||
165 | case ARG_WIDTH: | ||
166 | width = strtoul (arg, NULL, 0); | ||
167 | if (!width) | ||
168 | { | ||
169 | argp_error (state, _("invalid width")); | ||
170 | exit (1); | ||
171 | } | ||
172 | break; | ||
173 | |||
174 | case ARG_EDITOR: | ||
175 | wh_env.editor = arg; | ||
176 | break; | ||
177 | 59 | ||
178 | case ARG_FOLDER: | 60 | static void |
179 | mh_set_current_folder (arg); | 61 | clear_filter (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
180 | break; | 62 | { |
63 | mhl_filter_file = NULL; | ||
64 | encap = encap_clear; | ||
65 | } | ||
181 | 66 | ||
182 | case ARG_FORM: | 67 | static void |
183 | mh_find_file (arg, &formfile); | 68 | set_mime (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
184 | break; | 69 | { |
70 | if (strcmp (arg, "1") == 0) | ||
71 | encap = encap_mime; | ||
72 | else | ||
73 | encap = encap_clear; | ||
74 | } | ||
185 | 75 | ||
186 | case ARG_FORMAT: | 76 | static void |
187 | if (is_true (arg)) | 77 | set_format (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
78 | { | ||
79 | if (arg) | ||
188 | { | 80 | { |
189 | encap = encap_mhl; | 81 | encap = encap_mhl; |
190 | mh_find_file ("mhl.forward", &mhl_filter_file); | 82 | mh_find_file ("mhl.forward", &mhl_filter_file); |
191 | } | 83 | } |
192 | else | 84 | else |
193 | encap = encap_clear; | 85 | encap = encap_clear; |
194 | break; | ||
195 | |||
196 | case ARG_NOFORMAT: | ||
197 | encap = encap_clear; | ||
198 | break; | ||
199 | |||
200 | case ARG_FILTER: | ||
201 | mh_find_file (arg, &mhl_filter_file); | ||
202 | encap = encap_mhl; | ||
203 | break; | ||
204 | |||
205 | case ARG_MIME: | ||
206 | if (is_true (arg)) | ||
207 | { | ||
208 | encap = encap_mime; | ||
209 | break; | ||
210 | } | ||
211 | /*FALLTHRU*/ | ||
212 | case ARG_NOMIME: | ||
213 | if (encap == encap_mime) | ||
214 | encap = encap_clear; | ||
215 | break; | ||
216 | |||
217 | case ARG_INPLACE: | ||
218 | mh_opt_notimpl_warning ("-inplace"); | ||
219 | break; | ||
220 | |||
221 | case ARG_WHATNOWPROC: | ||
222 | whatnowproc = arg; | ||
223 | break; | ||
224 | |||
225 | case ARG_NOWHATNOWPROC: | ||
226 | nowhatnowproc = 1; | ||
227 | break; | ||
228 | |||
229 | case ARGP_KEY_FINI: | ||
230 | if (!formfile) | ||
231 | mh_find_file ("forwcomps", &formfile); | ||
232 | break; | ||
233 | |||
234 | default: | ||
235 | return ARGP_ERR_UNKNOWN; | ||
236 | } | ||
237 | return 0; | ||
238 | } | 86 | } |
239 | 87 | ||
88 | static struct mu_option options[] = { | ||
89 | { "annotate", 0, NULL, MU_OPTION_DEFAULT, | ||
90 | N_("add Forwarded: header to each forwarded message"), | ||
91 | mu_c_bool, &annotate }, | ||
92 | { "build", 0, NULL, MU_OPTION_DEFAULT, | ||
93 | N_("build the draft and quit immediately"), | ||
94 | mu_c_bool, &build_only }, | ||
95 | { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
96 | N_("specify the folder for message drafts"), | ||
97 | mu_c_string, &draftfolder }, | ||
98 | { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT, | ||
99 | N_("undo the effect of the last --draftfolder option"), | ||
100 | mu_c_string, &draftfolder, mh_opt_clear_string }, | ||
101 | { "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT, | ||
102 | N_("invoke the draftmessage facility"), | ||
103 | mu_c_string, &draftmessage }, | ||
104 | { "editor", 0, N_("PROG"), MU_OPTION_DEFAULT, | ||
105 | N_("set the editor program to use"), | ||
106 | mu_c_string, &wh_env.editor }, | ||
107 | { "noedit", 0, NULL, MU_OPTION_DEFAULT, | ||
108 | N_("suppress the initial edit"), | ||
109 | mu_c_int, &initial_edit, NULL, "0" }, | ||
110 | { "file", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
111 | N_("read message from FILE"), | ||
112 | mu_c_string, &input_file }, | ||
113 | { "format", 0, NULL, MU_OPTION_DEFAULT, | ||
114 | N_("format messages"), | ||
115 | mu_c_bool, NULL, set_format }, | ||
116 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
117 | N_("read format from given file"), | ||
118 | mu_c_string, &formfile, mh_opt_find_file }, | ||
119 | { "filter", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
120 | N_("use filter FILE to preprocess the body of the message"), | ||
121 | mu_c_string, NULL, set_filter }, | ||
122 | { "nofilter", 0, NULL, MU_OPTION_DEFAULT, | ||
123 | N_("undo the effect of the last --filter option"), | ||
124 | mu_c_string, NULL, clear_filter }, | ||
125 | { "inplace", 0, NULL, MU_OPTION_HIDDEN, | ||
126 | N_("annotate the message in place"), | ||
127 | mu_c_bool, NULL, mh_opt_notimpl_warning }, | ||
128 | { "mime", 0, NULL, MU_OPTION_DEFAULT, | ||
129 | N_("use MIME encapsulation"), | ||
130 | mu_c_bool, NULL, set_mime }, | ||
131 | { "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT, | ||
132 | N_("Set output width"), | ||
133 | mu_c_int, &width }, | ||
134 | { "whatnowproc", 0, N_("PROG"), MU_OPTION_DEFAULT, | ||
135 | N_("set the replacement for whatnow program"), | ||
136 | mu_c_string, &whatnowproc }, | ||
137 | { "nowhatnowproc", 0, NULL, MU_OPTION_DEFAULT, | ||
138 | N_("don't run whatnowproc"), | ||
139 | mu_c_int, &nowhatnowproc, NULL, "1" }, | ||
140 | { "use", 0, NULL, MU_OPTION_DEFAULT, | ||
141 | N_("use draft file preserved after the last session"), | ||
142 | mu_c_bool, &use_draft }, | ||
143 | MU_OPTION_END | ||
144 | }; | ||
145 | |||
240 | struct format_data | 146 | struct format_data |
241 | { | 147 | { |
242 | int num; | 148 | int num; |
... | @@ -475,17 +381,17 @@ finish_draft () | ... | @@ -475,17 +381,17 @@ finish_draft () |
475 | int | 381 | int |
476 | main (int argc, char **argv) | 382 | main (int argc, char **argv) |
477 | { | 383 | { |
478 | int index, rc; | 384 | int rc; |
479 | 385 | ||
480 | /* Native Language Support */ | 386 | /* Native Language Support */ |
481 | MU_APP_INIT_NLS (); | 387 | MU_APP_INIT_NLS (); |
482 | 388 | ||
483 | mh_argp_init (); | 389 | draftfolder = mh_global_profile_get ("Draft-Folder", NULL); |
484 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 390 | whatnowproc = mh_global_profile_get ("whatnowproc", NULL); |
485 | opt_handler, NULL, &index); | 391 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
486 | 392 | args_doc, prog_doc, NULL); | |
487 | argc -= index; | 393 | if (!formfile) |
488 | argv += index; | 394 | mh_find_file ("forwcomps", &formfile); |
489 | 395 | ||
490 | if (input_file) | 396 | if (input_file) |
491 | { | 397 | { | ... | ... |
... | @@ -20,71 +20,14 @@ | ... | @@ -20,71 +20,14 @@ |
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | #include "muscript.h" | 21 | #include "muscript.h" |
22 | 22 | ||
23 | static char doc[] = N_("GNU MH inc")"\v" | 23 | static char prog_doc[] = N_("GNU MH inc"); |
24 | N_("Debug flags are:\n\ | 24 | static char extra_doc[] = N_("Debug flags are:\n\ |
25 | g - guile stack traces\n\ | 25 | g - guile stack traces\n\ |
26 | t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\ | 26 | t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\ |
27 | i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\ | 27 | i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\ |
28 | l - sieve action logs\n\n\ | 28 | l - sieve action logs"); |
29 | Use -help to obtain the list of traditional MH options."); | ||
30 | static char args_doc[] = N_("[+FOLDER]"); | 29 | static char args_doc[] = N_("[+FOLDER]"); |
31 | 30 | ||
32 | /* GNU options */ | ||
33 | static struct argp_option options[] = { | ||
34 | {"file", ARG_FILE, N_("FILE"), 0, | ||
35 | N_("incorporate mail from named file")}, | ||
36 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
37 | N_("specify folder to incorporate mail to")}, | ||
38 | {"audit", ARG_AUDIT, N_("FILE"), 0, | ||
39 | N_("enable audit")}, | ||
40 | {"noaudit", ARG_NOAUDIT, 0, 0, | ||
41 | N_("disable audit")}, | ||
42 | {"changecur", ARG_CHANGECUR, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
43 | N_("mark first incorporated message as current (default)")}, | ||
44 | {"nochangecur", ARG_NOCHANGECUR, NULL, OPTION_HIDDEN, ""}, | ||
45 | {"form", ARG_FORM, N_("FILE"), 0, | ||
46 | N_("read format from given file")}, | ||
47 | {"format", ARG_FORMAT, N_("FORMAT"), 0, | ||
48 | N_("use this format string")}, | ||
49 | {"truncate", ARG_TRUNCATE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
50 | N_("truncate source mailbox after incorporating (default)")}, | ||
51 | {"notruncate", ARG_NOTRUNCATE, NULL, OPTION_HIDDEN, ""}, | ||
52 | {"moveto", ARG_MOVETO, N_("MAILBOX"), 0, | ||
53 | N_("move incorporated messages to MAILBOX instead of deleting them") }, | ||
54 | {"width", ARG_WIDTH, N_("NUMBER"), 0, | ||
55 | N_("set output width")}, | ||
56 | {"quiet", ARG_QUIET, 0, 0, | ||
57 | N_("be quiet")}, | ||
58 | {"notify", ARG_NOTIFY,N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
59 | N_("enable biff notification"), }, | ||
60 | {"language",ARG_LANG, N_("LANG"), 0, | ||
61 | N_("set language for the --script option") }, | ||
62 | {"script", ARG_SCRIPT,N_("FILE"), 0, | ||
63 | N_("filter incoming messages using script FILE") }, | ||
64 | {"debug", ARG_DEBUG, N_("FLAGS"), 0, | ||
65 | N_("enable debugging") }, | ||
66 | { 0 } | ||
67 | }; | ||
68 | |||
69 | /* Traditional MH options */ | ||
70 | struct mh_option mh_option[] = { | ||
71 | { "audit", MH_OPT_ARG, "audit-file" }, | ||
72 | { "noaudit" }, | ||
73 | { "changecur", MH_OPT_BOOL }, | ||
74 | { "file", MH_OPT_ARG, "input-file" }, | ||
75 | { "form", MH_OPT_ARG, "format-file" }, | ||
76 | { "format", MH_OPT_ARG, "string" }, | ||
77 | { "truncate", MH_OPT_BOOL }, | ||
78 | { "moveto", MH_OPT_ARG, "folder" }, | ||
79 | { "width", MH_OPT_ARG, "number" }, | ||
80 | { "notify", MH_OPT_BOOL }, | ||
81 | { "quiet" }, | ||
82 | { "language", MH_OPT_ARG, "lang" }, | ||
83 | { "script", MH_OPT_ARG, "file" }, | ||
84 | { "debug", MH_OPT_ARG, "flags" }, | ||
85 | { NULL } | ||
86 | }; | ||
87 | |||
88 | static char *format_str = mh_list_format; | 31 | static char *format_str = mh_list_format; |
89 | static int width = 80; | 32 | static int width = 80; |
90 | static mu_list_t input_file_list; | 33 | static mu_list_t input_file_list; |
... | @@ -99,53 +42,10 @@ static const char *move_to_mailbox; | ... | @@ -99,53 +42,10 @@ static const char *move_to_mailbox; |
99 | static const char *script_file; | 42 | static const char *script_file; |
100 | static const char *script_lang; | 43 | static const char *script_lang; |
101 | 44 | ||
102 | static error_t | 45 | static void |
103 | opt_handler (int key, char *arg, struct argp_state *state) | 46 | add_file (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
104 | { | 47 | { |
105 | int rc; | 48 | int rc; |
106 | char *p; | ||
107 | |||
108 | switch (key) | ||
109 | { | ||
110 | case ARGP_KEY_FINI: | ||
111 | if (!append_folder) | ||
112 | append_folder = mh_global_profile_get ("Inbox", "inbox"); | ||
113 | break; | ||
114 | |||
115 | case ARG_AUDIT: | ||
116 | audit_file = arg; | ||
117 | break; | ||
118 | |||
119 | case ARG_NOAUDIT: | ||
120 | audit_file = NULL; | ||
121 | break; | ||
122 | |||
123 | case ARG_CHANGECUR: | ||
124 | changecur = is_true (arg); | ||
125 | break; | ||
126 | |||
127 | case ARG_DEBUG: | ||
128 | if (mu_script_debug_flags (arg, &p)) | ||
129 | argp_error (state, _("invalid debug flag near %s"), p); | ||
130 | break; | ||
131 | |||
132 | case ARG_NOCHANGECUR: | ||
133 | changecur = 0; | ||
134 | break; | ||
135 | |||
136 | case ARG_FOLDER: | ||
137 | append_folder = arg; | ||
138 | break; | ||
139 | |||
140 | case ARG_FORM: | ||
141 | mh_read_formfile (arg, &format_str); | ||
142 | break; | ||
143 | |||
144 | case ARG_FORMAT: | ||
145 | format_str = arg; | ||
146 | break; | ||
147 | |||
148 | case ARG_FILE: | ||
149 | if (!input_file_list) | 49 | if (!input_file_list) |
150 | { | 50 | { |
151 | rc = mu_list_create (&input_file_list); | 51 | rc = mu_list_create (&input_file_list); |
... | @@ -156,57 +56,75 @@ opt_handler (int key, char *arg, struct argp_state *state) | ... | @@ -156,57 +56,75 @@ opt_handler (int key, char *arg, struct argp_state *state) |
156 | exit (1); | 56 | exit (1); |
157 | } | 57 | } |
158 | } | 58 | } |
159 | rc = mu_list_append (input_file_list, arg); | 59 | rc = mu_list_append (input_file_list, mu_strdup (arg)); |
160 | if (rc) | 60 | if (rc) |
161 | { | 61 | { |
162 | mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", arg, rc); | 62 | mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", arg, rc); |
163 | exit (1); | 63 | exit (1); |
164 | } | 64 | } |
165 | break; | 65 | } |
166 | |||
167 | case ARG_TRUNCATE: | ||
168 | truncate_source = is_true (arg); | ||
169 | break; | ||
170 | |||
171 | case ARG_NOTRUNCATE: | ||
172 | truncate_source = 0; | ||
173 | break; | ||
174 | 66 | ||
175 | case ARG_MOVETO: | 67 | static void |
176 | move_to_mailbox = arg; | 68 | set_debug (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
177 | break; | 69 | { |
70 | char *p; | ||
178 | 71 | ||
179 | case ARG_WIDTH: | 72 | if (mu_script_debug_flags (arg, &p)) |
180 | width = strtoul (arg, NULL, 0); | ||
181 | if (!width) | ||
182 | { | 73 | { |
183 | argp_error (state, _("invalid width")); | 74 | mu_parseopt_error (po, _("invalid debug flag near %s"), p); |
184 | exit (1); | 75 | exit (po->po_exit_error); |
185 | } | ||
186 | break; | ||
187 | |||
188 | case ARG_QUIET: | ||
189 | quiet = 1; | ||
190 | break; | ||
191 | |||
192 | case ARG_NOTIFY: | ||
193 | notify = is_true (arg);; | ||
194 | break; | ||
195 | |||
196 | case ARG_LANG: | ||
197 | script_lang = arg; | ||
198 | break; | ||
199 | |||
200 | case ARG_SCRIPT: | ||
201 | script_file = arg; | ||
202 | break; | ||
203 | |||
204 | default: | ||
205 | return ARGP_ERR_UNKNOWN; | ||
206 | } | 76 | } |
207 | return 0; | ||
208 | } | 77 | } |
209 | 78 | ||
79 | static struct mu_option options[] = { | ||
80 | { "file", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
81 | N_("incorporate mail from named file"), | ||
82 | mu_c_string, NULL, add_file }, | ||
83 | { "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT, | ||
84 | N_("specify folder to incorporate mail to"), | ||
85 | mu_c_string, &append_folder }, | ||
86 | { "audit", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
87 | N_("enable audit"), | ||
88 | mu_c_string, &audit_file }, | ||
89 | { "noaudit", 0, NULL, MU_OPTION_DEFAULT, | ||
90 | N_("disable audit"), | ||
91 | mu_c_string, &audit_file, mh_opt_clear_string }, | ||
92 | { "changecur", 0, NULL, MU_OPTION_DEFAULT, | ||
93 | N_("mark first incorporated message as current (default)"), | ||
94 | mu_c_bool, &changecur }, | ||
95 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
96 | N_("read format from given file"), | ||
97 | mu_c_string, &format_str, mh_opt_read_formfile }, | ||
98 | { "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT, | ||
99 | N_("use this format string"), | ||
100 | mu_c_string, &format_str }, | ||
101 | { "truncate", 0, NULL, MU_OPTION_DEFAULT, | ||
102 | N_("truncate source mailbox after incorporating (default)"), | ||
103 | mu_c_bool, &truncate_source }, | ||
104 | { "moveto", 0, N_("MAILBOX"), MU_OPTION_DEFAULT, | ||
105 | N_("move incorporated messages to MAILBOX instead of deleting them"), | ||
106 | mu_c_string, &move_to_mailbox }, | ||
107 | { "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT, | ||
108 | N_("set output width"), | ||
109 | mu_c_int, &width }, | ||
110 | { "quiet", 0, NULL, MU_OPTION_DEFAULT, | ||
111 | N_("be quiet"), | ||
112 | mu_c_bool, &quiet }, | ||
113 | { "notify", 0, NULL, MU_OPTION_DEFAULT, | ||
114 | N_("enable biff notification"), | ||
115 | mu_c_bool, ¬ify }, | ||
116 | { "language", 0, N_("LANG"), MU_OPTION_DEFAULT, | ||
117 | N_("set language for the --script option"), | ||
118 | mu_c_string, &script_lang }, | ||
119 | { "script", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
120 | N_("filter incoming messages using script FILE"), | ||
121 | mu_c_string, &script_file }, | ||
122 | { "debug", 0, N_("FLAGS"), MU_OPTION_DEFAULT, | ||
123 | N_("enable debugging"), | ||
124 | mu_c_string, 0, set_debug }, | ||
125 | MU_OPTION_END | ||
126 | }; | ||
127 | |||
210 | void | 128 | void |
211 | list_message (mh_format_t *format, mu_mailbox_t mbox, size_t msgno, | 129 | list_message (mh_format_t *format, mu_mailbox_t mbox, size_t msgno, |
212 | size_t width) | 130 | size_t width) |
... | @@ -430,9 +348,10 @@ main (int argc, char **argv) | ... | @@ -430,9 +348,10 @@ main (int argc, char **argv) |
430 | /* Native Language Support */ | 348 | /* Native Language Support */ |
431 | MU_APP_INIT_NLS (); | 349 | MU_APP_INIT_NLS (); |
432 | 350 | ||
433 | mh_argp_init (); | 351 | mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, extra_doc); |
434 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 352 | if (!append_folder) |
435 | opt_handler, NULL, NULL); | 353 | append_folder = mh_global_profile_get ("Inbox", "inbox"); |
354 | |||
436 | mu_registrar_set_default_scheme ("mh"); | 355 | mu_registrar_set_default_scheme ("mh"); |
437 | 356 | ||
438 | /* Inc sets missing cur to 1 */ | 357 | /* Inc sets missing cur to 1 */ | ... | ... |
... | @@ -17,41 +17,17 @@ | ... | @@ -17,41 +17,17 @@ |
17 | 17 | ||
18 | #include <mh.h> | 18 | #include <mh.h> |
19 | 19 | ||
20 | static char doc[] = N_("GNU MH install-mh")"\v" | 20 | static char prog_doc[] = N_("GNU MH install-mh"); |
21 | N_("Use -help to obtain the list of traditional MH options."); | ||
22 | |||
23 | /* GNU options */ | ||
24 | static struct argp_option options[] = { | ||
25 | {"auto", ARG_AUTO, NULL, 0, N_("do not ask for anything")}, | ||
26 | {"compat", ARG_COMPAT, NULL, OPTION_HIDDEN, ""}, | ||
27 | {NULL} | ||
28 | }; | ||
29 | |||
30 | struct mh_option mh_option[] = { | ||
31 | { "auto" }, | ||
32 | { "compat" }, | ||
33 | { NULL } | ||
34 | }; | ||
35 | 21 | ||
36 | int automode; | 22 | int automode; |
37 | 23 | ||
38 | static error_t | 24 | static struct mu_option options[] = { |
39 | opt_handler (int key, char *arg, struct argp_state *state) | 25 | { "auto", 0, NULL, MU_OPTION_DEFAULT, |
40 | { | 26 | N_("do not ask for anything"), |
41 | switch (key) | 27 | mu_c_bool, &automode }, |
42 | { | 28 | { "compat", 0, NULL, MU_OPTION_HIDDEN, "", mu_c_void }, |
43 | case ARG_AUTO: | 29 | MU_OPTION_END |
44 | automode = 1; | 30 | }; |
45 | break; | ||
46 | |||
47 | case ARG_COMPAT: | ||
48 | break; | ||
49 | |||
50 | default: | ||
51 | return ARGP_ERR_UNKNOWN; | ||
52 | } | ||
53 | return 0; | ||
54 | } | ||
55 | 31 | ||
56 | int | 32 | int |
57 | main (int argc, char **argv) | 33 | main (int argc, char **argv) |
... | @@ -62,10 +38,8 @@ main (int argc, char **argv) | ... | @@ -62,10 +38,8 @@ main (int argc, char **argv) |
62 | /* Native Language Support */ | 38 | /* Native Language Support */ |
63 | MU_APP_INIT_NLS (); | 39 | MU_APP_INIT_NLS (); |
64 | 40 | ||
65 | mh_argp_init (); | ||
66 | mh_auto_install = 0; | 41 | mh_auto_install = 0; |
67 | mh_argp_parse (&argc, &argv, 0, options, mh_option, NULL, doc, | 42 | mh_getopt (&argc, &argv, options, 0, NULL, prog_doc, NULL); |
68 | opt_handler, NULL, NULL); | ||
69 | 43 | ||
70 | name = getenv ("MH"); | 44 | name = getenv ("MH"); |
71 | if (name) | 45 | if (name) | ... | ... |
... | @@ -17,106 +17,78 @@ | ... | @@ -17,106 +17,78 @@ |
17 | 17 | ||
18 | #include <mh.h> | 18 | #include <mh.h> |
19 | 19 | ||
20 | static char doc[] = N_("GNU MH mark")"\v" | 20 | static char prog_doc[] = N_("GNU MH mark"); |
21 | N_("Use -help to obtain the list of traditional MH options."); | ||
22 | static char args_doc[] = N_("[MSGLIST]"); | 21 | static char args_doc[] = N_("[MSGLIST]"); |
23 | 22 | ||
24 | /* GNU options */ | 23 | enum action_type |
25 | static struct argp_option options[] = { | 24 | { |
26 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | 25 | action_undef, |
27 | N_("specify folder to operate upon")}, | 26 | action_list, |
28 | {"sequence", ARG_SEQUENCE, N_("NAME"), 0, | 27 | action_add, |
29 | N_("specify sequence name to operate upon")}, | 28 | action_delete |
30 | {"add", ARG_ADD, NULL, 0, | 29 | }; |
31 | N_("add messages to the sequence")}, | 30 | static enum action_type action = action_undef; /* Action to perform */ |
32 | {"delete", ARG_DELETE, NULL, 0, | ||
33 | N_("delete messages from the sequence")}, | ||
34 | {"list", ARG_LIST, NULL, 0, | ||
35 | N_("list the sequences")}, | ||
36 | {"public", ARG_PUBLIC, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
37 | N_("create public sequence")}, | ||
38 | {"nopublic", ARG_NOPUBLIC, NULL, OPTION_HIDDEN, "" }, | ||
39 | {"zero", ARG_ZERO, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
40 | N_("empty the sequence before adding messages")}, | ||
41 | {"nozero", ARG_NOZERO, NULL, OPTION_HIDDEN, "" }, | ||
42 | {NULL} | ||
43 | }; | ||
44 | |||
45 | struct mh_option mh_option[] = { | ||
46 | { "sequence" }, | ||
47 | { "add" }, | ||
48 | { "delete" }, | ||
49 | { "list" }, | ||
50 | { "public", MH_OPT_BOOL }, | ||
51 | { "zero", MH_OPT_BOOL }, | ||
52 | { NULL } | ||
53 | }; | ||
54 | 31 | ||
55 | static int action; /* Action to perform */ | ||
56 | static int seq_flags = 0; /* Create public sequences; | 32 | static int seq_flags = 0; /* Create public sequences; |
57 | Do not zero the sequence before addition */ | 33 | Do not zero the sequence before addition */ |
58 | static mu_list_t seq_list; /* List of sequence names to operate upon */ | 34 | static mu_list_t seq_list; /* List of sequence names to operate upon */ |
59 | 35 | ||
60 | static const char *mbox_dir; | 36 | static const char *mbox_dir; |
37 | static int public_option = -1; | ||
38 | static int zero_option = -1; | ||
61 | 39 | ||
62 | static void | 40 | static void |
63 | add_sequence (char *name) | 41 | set_action_add (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
64 | { | 42 | { |
65 | if (!seq_list && mu_list_create (&seq_list)) | 43 | action = action_add; |
66 | { | ||
67 | mu_error (_("cannot create sequence list")); | ||
68 | exit (1); | ||
69 | } | ||
70 | mu_list_append (seq_list, name); | ||
71 | } | 44 | } |
72 | 45 | ||
73 | static error_t | 46 | static void |
74 | opt_handler (int key, char *arg, struct argp_state *state) | 47 | set_action_delete (struct mu_parseopt *po, struct mu_option *opt, |
48 | char const *arg) | ||
75 | { | 49 | { |
76 | switch (key) | 50 | action = action_delete; |
77 | { | 51 | } |
78 | case ARG_FOLDER: | ||
79 | mh_set_current_folder (arg); | ||
80 | break; | ||
81 | |||
82 | case ARG_SEQUENCE: | ||
83 | add_sequence (arg); | ||
84 | break; | ||
85 | |||
86 | case ARG_ADD: | ||
87 | case ARG_DELETE: | ||
88 | case ARG_LIST: | ||
89 | action = key; | ||
90 | break; | ||
91 | |||
92 | case ARG_PUBLIC: | ||
93 | if (is_true (arg)) | ||
94 | seq_flags &= ~SEQ_PRIVATE; | ||
95 | else | ||
96 | seq_flags |= SEQ_PRIVATE; | ||
97 | break; | ||
98 | |||
99 | case ARG_NOPUBLIC: | ||
100 | seq_flags |= SEQ_PRIVATE; | ||
101 | break; | ||
102 | |||
103 | case ARG_ZERO: | ||
104 | if (is_true (arg)) | ||
105 | seq_flags |= SEQ_ZERO; | ||
106 | else | ||
107 | seq_flags &= ~SEQ_ZERO; | ||
108 | break; | ||
109 | 52 | ||
110 | case ARG_NOZERO: | 53 | static void |
111 | seq_flags &= ~SEQ_ZERO; | 54 | set_action_list (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
112 | break; | 55 | { |
56 | action = action_list; | ||
57 | } | ||
113 | 58 | ||
114 | default: | 59 | static void |
115 | return ARGP_ERR_UNKNOWN; | 60 | add_sequence (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
61 | { | ||
62 | if (!seq_list && mu_list_create (&seq_list)) | ||
63 | { | ||
64 | mu_error (_("cannot create sequence list")); | ||
65 | exit (1); | ||
116 | } | 66 | } |
117 | return 0; | 67 | mu_list_append (seq_list, mu_strdup (arg)); |
118 | } | 68 | } |
119 | 69 | ||
70 | static struct mu_option options[] = { | ||
71 | { "sequence", 0, N_("NAME"), MU_OPTION_DEFAULT, | ||
72 | N_("specify sequence name to operate upon"), | ||
73 | mu_c_string, NULL, add_sequence }, | ||
74 | { "add", 0, NULL, MU_OPTION_DEFAULT, | ||
75 | N_("add messages to the sequence"), | ||
76 | mu_c_string, NULL, set_action_add }, | ||
77 | { "delete", 0, NULL, MU_OPTION_DEFAULT, | ||
78 | N_("delete messages from the sequence"), | ||
79 | mu_c_string, NULL, set_action_delete }, | ||
80 | { "list", 0, NULL, MU_OPTION_DEFAULT, | ||
81 | N_("list the sequences"), | ||
82 | mu_c_string, NULL, set_action_list }, | ||
83 | { "public", 0, NULL, MU_OPTION_DEFAULT, | ||
84 | N_("create public sequence"), | ||
85 | mu_c_bool, &public_option }, | ||
86 | { "zero", 0, NULL, MU_OPTION_DEFAULT, | ||
87 | N_("empty the sequence before adding messages"), | ||
88 | mu_c_bool, &zero_option }, | ||
89 | MU_OPTION_END | ||
90 | }; | ||
91 | |||
120 | 92 | ||
121 | struct mark_closure | 93 | struct mark_closure |
122 | { | 94 | { |
... | @@ -125,7 +97,7 @@ struct mark_closure | ... | @@ -125,7 +97,7 @@ struct mark_closure |
125 | }; | 97 | }; |
126 | 98 | ||
127 | static int | 99 | static int |
128 | action_add (void *item, void *data) | 100 | do_add (void *item, void *data) |
129 | { | 101 | { |
130 | struct mark_closure *clos = data; | 102 | struct mark_closure *clos = data; |
131 | mh_seq_add (clos->mbox, (char *)item, clos->msgset, seq_flags); | 103 | mh_seq_add (clos->mbox, (char *)item, clos->msgset, seq_flags); |
... | @@ -133,7 +105,7 @@ action_add (void *item, void *data) | ... | @@ -133,7 +105,7 @@ action_add (void *item, void *data) |
133 | } | 105 | } |
134 | 106 | ||
135 | static int | 107 | static int |
136 | action_delete (void *item, void *data) | 108 | do_delete (void *item, void *data) |
137 | { | 109 | { |
138 | struct mark_closure *clos = data; | 110 | struct mark_closure *clos = data; |
139 | mh_seq_delete (clos->mbox, (char *)item, clos->msgset, seq_flags); | 111 | mh_seq_delete (clos->mbox, (char *)item, clos->msgset, seq_flags); |
... | @@ -141,7 +113,7 @@ action_delete (void *item, void *data) | ... | @@ -141,7 +113,7 @@ action_delete (void *item, void *data) |
141 | } | 113 | } |
142 | 114 | ||
143 | static int | 115 | static int |
144 | action_list (void *item, void *data) | 116 | do_list (void *item, void *data) |
145 | { | 117 | { |
146 | struct mark_closure *clos = data; | 118 | struct mark_closure *clos = data; |
147 | char *name = item; | 119 | char *name = item; |
... | @@ -190,16 +162,38 @@ list_all (mu_mailbox_t mbox) | ... | @@ -190,16 +162,38 @@ list_all (mu_mailbox_t mbox) |
190 | int | 162 | int |
191 | main (int argc, char **argv) | 163 | main (int argc, char **argv) |
192 | { | 164 | { |
193 | int index; | ||
194 | mu_msgset_t msgset; | 165 | mu_msgset_t msgset; |
195 | mu_mailbox_t mbox; | 166 | mu_mailbox_t mbox; |
196 | mu_url_t url; | 167 | mu_url_t url; |
197 | struct mark_closure clos; | 168 | struct mark_closure clos; |
198 | 169 | ||
199 | MU_APP_INIT_NLS (); | 170 | MU_APP_INIT_NLS (); |
200 | mh_argp_init (); | 171 | |
201 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 172 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
202 | opt_handler, NULL, &index); | 173 | args_doc, prog_doc, NULL); |
174 | if (public_option == -1) | ||
175 | /* use default */; | ||
176 | else if (public_option) | ||
177 | seq_flags &= ~SEQ_PRIVATE; | ||
178 | else | ||
179 | seq_flags |= SEQ_PRIVATE; | ||
180 | |||
181 | if (zero_option == -1) | ||
182 | /* use default */; | ||
183 | else if (zero_option) | ||
184 | seq_flags |= SEQ_ZERO; | ||
185 | else | ||
186 | seq_flags &= ~SEQ_ZERO; | ||
187 | |||
188 | if (action == action_undef) | ||
189 | { | ||
190 | /* If no explicit action is given, assume -add if a sequence | ||
191 | was specified, and -list otherwise. */ | ||
192 | if (mu_list_is_empty (seq_list)) | ||
193 | action = action_list; | ||
194 | else | ||
195 | action = action_add; | ||
196 | } | ||
203 | 197 | ||
204 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); | 198 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); |
205 | mu_mailbox_get_url (mbox, &url); | 199 | mu_mailbox_get_url (mbox, &url); |
... | @@ -207,8 +201,6 @@ main (int argc, char **argv) | ... | @@ -207,8 +201,6 @@ main (int argc, char **argv) |
207 | if (memcmp (mbox_dir, "mh:", 3) == 0) | 201 | if (memcmp (mbox_dir, "mh:", 3) == 0) |
208 | mbox_dir += 3; | 202 | mbox_dir += 3; |
209 | 203 | ||
210 | argc -= index; | ||
211 | argv += index; | ||
212 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); | 204 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); |
213 | 205 | ||
214 | clos.mbox = mbox; | 206 | clos.mbox = mbox; |
... | @@ -216,32 +208,34 @@ main (int argc, char **argv) | ... | @@ -216,32 +208,34 @@ main (int argc, char **argv) |
216 | //FIXME: msgset operates on UIDs but there's no way to inform it about that. | 208 | //FIXME: msgset operates on UIDs but there's no way to inform it about that. |
217 | switch (action) | 209 | switch (action) |
218 | { | 210 | { |
219 | case ARG_ADD: | 211 | case action_add: |
220 | if (!seq_list) | 212 | if (!seq_list) |
221 | { | 213 | { |
222 | mu_error (_("--add requires at least one --sequence argument")); | 214 | mu_error (_("--add requires at least one --sequence argument")); |
223 | return 1; | 215 | return 1; |
224 | } | 216 | } |
225 | mu_list_foreach (seq_list, action_add, (void *) &clos); | 217 | mu_list_foreach (seq_list, do_add, (void *) &clos); |
226 | mh_global_save_state (); | 218 | mh_global_save_state (); |
227 | break; | 219 | break; |
228 | 220 | ||
229 | case ARG_DELETE: | 221 | case action_delete: |
230 | if (!seq_list) | 222 | if (!seq_list) |
231 | { | 223 | { |
232 | mu_error (_("--delete requires at least one --sequence argument")); | 224 | mu_error (_("--delete requires at least one --sequence argument")); |
233 | return 1; | 225 | return 1; |
234 | } | 226 | } |
235 | mu_list_foreach (seq_list, action_delete, (void *) &clos); | 227 | mu_list_foreach (seq_list, do_delete, (void *) &clos); |
236 | mh_global_save_state (); | 228 | mh_global_save_state (); |
237 | break; | 229 | break; |
238 | 230 | ||
239 | case ARG_LIST: | 231 | case action_list: |
240 | if (!seq_list) | 232 | if (!seq_list) |
241 | list_all (mbox); | 233 | list_all (mbox); |
242 | else | 234 | else |
243 | mu_list_foreach (seq_list, action_list, &clos); | 235 | mu_list_foreach (seq_list, do_list, &clos); |
244 | break; | 236 | break; |
237 | default: | ||
238 | abort (); | ||
245 | } | 239 | } |
246 | mu_mailbox_close (mbox); | 240 | mu_mailbox_close (mbox); |
247 | mu_mailbox_destroy (&mbox); | 241 | mu_mailbox_destroy (&mbox); | ... | ... |
... | @@ -57,6 +57,7 @@ | ... | @@ -57,6 +57,7 @@ |
57 | #include <mailutils/io.h> | 57 | #include <mailutils/io.h> |
58 | #include <mailutils/property.h> | 58 | #include <mailutils/property.h> |
59 | #include <mailutils/prog.h> | 59 | #include <mailutils/prog.h> |
60 | #include <mailutils/opool.h> | ||
60 | #include <mailutils/mh.h> | 61 | #include <mailutils/mh.h> |
61 | #include <mailutils/stdstream.h> | 62 | #include <mailutils/stdstream.h> |
62 | #include <mailutils/datetime.h> | 63 | #include <mailutils/datetime.h> |
... | @@ -230,7 +231,7 @@ extern int mh_mailbox_cur_default; | ... | @@ -230,7 +231,7 @@ extern int mh_mailbox_cur_default; |
230 | void mh_init (void); | 231 | void mh_init (void); |
231 | void mh_init2 (void); | 232 | void mh_init2 (void); |
232 | void mh_read_profile (void); | 233 | void mh_read_profile (void); |
233 | int mh_read_formfile (char *name, char **pformat); | 234 | int mh_read_formfile (char const *name, char **pformat); |
234 | mu_message_t mh_file_to_message (const char *folder, const char *file_name); | 235 | mu_message_t mh_file_to_message (const char *folder, const char *file_name); |
235 | mu_message_t mh_stream_to_message (mu_stream_t stream); | 236 | mu_message_t mh_stream_to_message (mu_stream_t stream); |
236 | void mh_install (char *name, int automode); | 237 | void mh_install (char *name, int automode); |
... | @@ -342,7 +343,7 @@ void mh_set_reply_regex (const char *str); | ... | @@ -342,7 +343,7 @@ void mh_set_reply_regex (const char *str); |
342 | int mh_decode_2047 (char *text, char **decoded_text); | 343 | int mh_decode_2047 (char *text, char **decoded_text); |
343 | const char *mh_charset (const char *); | 344 | const char *mh_charset (const char *); |
344 | 345 | ||
345 | int mh_alias_read (char *name, int fail); | 346 | int mh_alias_read (char const *name, int fail); |
346 | int mh_alias_get (const char *name, mu_list_t *return_list); | 347 | int mh_alias_get (const char *name, mu_list_t *return_list); |
347 | int mh_alias_get_address (const char *name, mu_address_t *addr, int *incl); | 348 | int mh_alias_get_address (const char *name, mu_address_t *addr, int *incl); |
348 | int mh_alias_get_alias (const char *uname, mu_list_t *return_list); | 349 | int mh_alias_get_alias (const char *uname, mu_list_t *return_list); | ... | ... |
... | @@ -419,7 +419,7 @@ yywrap () | ... | @@ -419,7 +419,7 @@ yywrap () |
419 | 419 | ||
420 | /* Parses the named alias file */ | 420 | /* Parses the named alias file */ |
421 | int | 421 | int |
422 | mh_alias_read (char *name, int fail) | 422 | mh_alias_read (char const *name, int fail) |
423 | { | 423 | { |
424 | extern int yydebug; | 424 | extern int yydebug; |
425 | char *p = getenv("ALI_YYDEBUG"); | 425 | char *p = getenv("ALI_YYDEBUG"); | ... | ... |
mh/mh_argp.c
deleted
100644 → 0
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999-2002, 2005-2007, 2009-2012, 2014-2016 Free | ||
3 | Software Foundation, Inc. | ||
4 | |||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Mailutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | /* Coexistence between GNU long options, traditional UNIX-style short | ||
19 | options and traditional MH long options. */ | ||
20 | |||
21 | #ifdef HAVE_CONFIG_H | ||
22 | # include <config.h> | ||
23 | #endif | ||
24 | |||
25 | #include <mh.h> | ||
26 | #include <string.h> | ||
27 | #include <mailutils/argcv.h> | ||
28 | #include "argp.h" | ||
29 | #ifdef MU_ALPHA_RELEASE | ||
30 | # include <git-describe.h> | ||
31 | #endif | ||
32 | |||
33 | static error_t | ||
34 | parse_opt (int key, char *arg, struct argp_state *state) | ||
35 | { | ||
36 | struct mh_argp_data *data = state->input; | ||
37 | error_t ret = ARGP_ERR_UNKNOWN; | ||
38 | |||
39 | switch (key) | ||
40 | { | ||
41 | case ARGP_KEY_ARG: | ||
42 | if (arg[0] == '+') | ||
43 | ret = data->handler (ARG_FOLDER, arg + 1, state); | ||
44 | break; | ||
45 | |||
46 | default: | ||
47 | ret = data->handler (key, arg, state); | ||
48 | if (ret == 0) | ||
49 | { | ||
50 | if (key == ARGP_KEY_ERROR) | ||
51 | data->errind = state->next; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | return ret; | ||
56 | } | ||
57 | |||
58 | static int | ||
59 | my_argp_parse (struct argp *argp, int argc, char **argv, int flags, | ||
60 | int *end_index, struct mh_argp_data *data) | ||
61 | { | ||
62 | int rc; | ||
63 | int f = 0; | ||
64 | int index = 0; | ||
65 | |||
66 | if (flags & ARGP_NO_ERRS) | ||
67 | { | ||
68 | while (argc > 0 | ||
69 | && (rc = argp_parse (argp, argc, argv, flags|f, end_index, data)) | ||
70 | == EINVAL) | ||
71 | { | ||
72 | if (data->errind == -1) | ||
73 | break; | ||
74 | data->errind--; | ||
75 | if (f) | ||
76 | data->errind--; | ||
77 | argc -= data->errind; | ||
78 | argv += data->errind; | ||
79 | index += data->errind; | ||
80 | if (argc < 2 || memcmp (argv[1], "--", 2)) | ||
81 | { | ||
82 | if (end_index) | ||
83 | *end_index = index + 1; | ||
84 | break; | ||
85 | } | ||
86 | f = ARGP_PARSE_ARGV0; | ||
87 | } | ||
88 | if (rc == 0 && end_index) | ||
89 | *end_index += index; | ||
90 | rc = 0; | ||
91 | } | ||
92 | else | ||
93 | rc = argp_parse (argp, argc, argv, flags, end_index, data); | ||
94 | return rc; | ||
95 | } | ||
96 | |||
97 | const char version_etc_copyright[] = | ||
98 | /* Do *not* mark this string for translation. %s is a copyright | ||
99 | symbol suitable for this locale, and %d is the copyright | ||
100 | year. */ | ||
101 | "Copyright %s 2010 Free Software Foundation, inc."; | ||
102 | |||
103 | /* This is almost the same as mu_program_version_hook from muinit.c, | ||
104 | except for different formatting of the first line. MH uses: | ||
105 | |||
106 | progname (GNU Mailutils X.Y.Z) | ||
107 | |||
108 | where X.Y.Z stands for the version number. Emacs MH-E uses this | ||
109 | to determine Mailutils presence and its version number (see | ||
110 | lisp/mh-e/mh-e.el, function mh-variant-mu-mh-info). */ | ||
111 | static void | ||
112 | mh_program_version_hook (FILE *stream, struct argp_state *state) | ||
113 | { | ||
114 | #ifdef GIT_DESCRIBE | ||
115 | fprintf (stream, "%s (%s %s) [%s]\n", | ||
116 | mu_program_name, PACKAGE_NAME, PACKAGE_VERSION, GIT_DESCRIBE); | ||
117 | #else | ||
118 | fprintf (stream, "%s (%s %s)\n", mu_program_name, | ||
119 | PACKAGE_NAME, PACKAGE_VERSION); | ||
120 | #endif | ||
121 | /* TRANSLATORS: Translate "(C)" to the copyright symbol | ||
122 | (C-in-a-circle), if this symbol is available in the user's | ||
123 | locale. Otherwise, do not translate "(C)"; leave it as-is. */ | ||
124 | fprintf (stream, version_etc_copyright, _("(C)")); | ||
125 | |||
126 | fputs (_("\ | ||
127 | \n\ | ||
128 | 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\ | ||
129 | There is NO WARRANTY, to the extent permitted by law.\n\ | ||
130 | \n\ | ||
131 | "), | ||
132 | stream); | ||
133 | } | ||
134 | |||
135 | void | ||
136 | mh_argp_init () | ||
137 | { | ||
138 | argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; | ||
139 | argp_program_version_hook = mh_program_version_hook; | ||
140 | } | ||
141 | |||
142 | |||
143 | enum | ||
144 | { | ||
145 | OPT_DEBUG_LEVEL = 256, | ||
146 | OPT_DEBUG_LINE_INFO, | ||
147 | }; | ||
148 | |||
149 | static struct argp_option mu_debug_argp_options[] = | ||
150 | { | ||
151 | { "debug-level", OPT_DEBUG_LEVEL, N_("LEVEL"), 0, | ||
152 | N_("set Mailutils debugging level"), 0 }, | ||
153 | { "debug-line-info", OPT_DEBUG_LINE_INFO, NULL, 0, | ||
154 | N_("show source info with debugging messages"), 0 }, | ||
155 | { NULL } | ||
156 | }; | ||
157 | |||
158 | static error_t | ||
159 | mu_debug_argp_parser (int key, char *arg, struct argp_state *state) | ||
160 | { | ||
161 | switch (key) | ||
162 | { | ||
163 | case OPT_DEBUG_LEVEL: | ||
164 | mu_debug_parse_spec (arg); | ||
165 | break; | ||
166 | |||
167 | case OPT_DEBUG_LINE_INFO: | ||
168 | mu_debug_line_info = 1; | ||
169 | break; | ||
170 | |||
171 | default: | ||
172 | return ARGP_ERR_UNKNOWN; | ||
173 | } | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | struct argp mu_debug_argp = { | ||
178 | mu_debug_argp_options, | ||
179 | mu_debug_argp_parser, | ||
180 | }; | ||
181 | |||
182 | struct argp_child mh_argp_children[] = { | ||
183 | { &mu_debug_argp, 0, N_("Global debugging settings"), -2 }, | ||
184 | { NULL } | ||
185 | }; | ||
186 | |||
187 | int | ||
188 | mh_argp_parse (int *pargc, char **pargv[], | ||
189 | int flags, | ||
190 | struct argp_option *option, | ||
191 | struct mh_option *mh_option, | ||
192 | char *argp_doc, char *doc, | ||
193 | argp_parser_t handler, | ||
194 | void *closure, int *pindex) | ||
195 | { | ||
196 | struct argp argp; | ||
197 | struct mh_argp_data data; | ||
198 | const char *val; | ||
199 | int index; | ||
200 | int extra = 0; | ||
201 | |||
202 | mu_set_program_name ((*pargv)[0]); | ||
203 | mh_init (); | ||
204 | |||
205 | mh_option_init (mh_option); | ||
206 | memset (&argp, 0, sizeof (argp)); | ||
207 | argp.options = option; | ||
208 | argp.parser = parse_opt; | ||
209 | argp.args_doc = argp_doc; | ||
210 | argp.doc = doc; | ||
211 | argp.children = mh_argp_children; | ||
212 | data.mh_option = mh_option; | ||
213 | data.closure = closure; | ||
214 | data.handler = handler; | ||
215 | data.doc = argp_doc; | ||
216 | data.errind = -1; | ||
217 | |||
218 | val = mh_global_profile_get (mu_program_name, NULL); | ||
219 | if (val) | ||
220 | { | ||
221 | int argc; | ||
222 | char **argv; | ||
223 | int i, j; | ||
224 | struct mu_wordsplit ws; | ||
225 | |||
226 | if (mu_wordsplit (val, &ws, MU_WRDSF_DEFFLAGS)) | ||
227 | { | ||
228 | mu_error (_("cannot split line `%s': %s"), val, | ||
229 | mu_wordsplit_strerror (&ws)); | ||
230 | exit (1); | ||
231 | } | ||
232 | |||
233 | argc = *pargc + ws.ws_wordc; | ||
234 | argv = calloc (argc + 1, sizeof *argv); | ||
235 | if (!argv) | ||
236 | mh_err_memory (1); | ||
237 | |||
238 | i = 0; | ||
239 | argv[i++] = (*pargv)[0]; | ||
240 | for (j = 0; j < ws.ws_wordc; i++, j++) | ||
241 | argv[i] = ws.ws_wordv[j]; | ||
242 | for (j = 1; i < argc; i++, j++) | ||
243 | argv[i] = (*pargv)[j]; | ||
244 | argv[i] = NULL; | ||
245 | |||
246 | ws.ws_wordc = 0; | ||
247 | mu_wordsplit_free (&ws); | ||
248 | |||
249 | mh_argv_preproc (argc, argv, &data); | ||
250 | |||
251 | my_argp_parse (&argp, argc, argv, flags, &index, &data); | ||
252 | |||
253 | extra = index < argc; | ||
254 | |||
255 | *pargc = argc; | ||
256 | *pargv = argv; | ||
257 | } | ||
258 | else | ||
259 | { | ||
260 | mh_argv_preproc (*pargc, *pargv, &data); | ||
261 | my_argp_parse (&argp, *pargc, *pargv, flags, &index, &data); | ||
262 | extra = index < *pargc; | ||
263 | } | ||
264 | if (pindex) | ||
265 | *pindex = index; | ||
266 | else if (extra) | ||
267 | { | ||
268 | mu_error (_("Extra arguments")); | ||
269 | exit (1); | ||
270 | } | ||
271 | mh_init2 (); | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | void | ||
276 | mh_license (const char *name) | ||
277 | { | ||
278 | printf (_("This is %s\n\n"), name); | ||
279 | printf ( | ||
280 | _(" GNU Mailutils is free software; you can redistribute it and/or modify\n" | ||
281 | " it under the terms of the GNU General Public License as published by\n" | ||
282 | " the Free Software Foundation; either version 3 of the License, or\n" | ||
283 | " (at your option) any later version.\n" | ||
284 | "\n" | ||
285 | " GNU Mailutils is distributed in the hope that it will be useful,\n" | ||
286 | " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" | ||
287 | " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" | ||
288 | " GNU General Public License for more details.\n" | ||
289 | "\n" | ||
290 | " You should have received a copy of the GNU General Public License along\n" | ||
291 | " with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.\n" | ||
292 | "\n" | ||
293 | "\n" | ||
294 | )); | ||
295 | |||
296 | exit (0); | ||
297 | } | ||
298 |
... | @@ -20,11 +20,10 @@ | ... | @@ -20,11 +20,10 @@ |
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | #include <mh_format.h> | 21 | #include <mh_format.h> |
22 | #include <mailutils/mime.h> | 22 | #include <mailutils/mime.h> |
23 | #include <mailutils/opool.h> | ||
23 | 24 | ||
24 | #ifdef HAVE_STRINGS_H | ||
25 | # include <strings.h> | ||
26 | #endif | ||
27 | #include <string.h> | 25 | #include <string.h> |
26 | #include <ctype.h> | ||
28 | #include "mbiter.h" | 27 | #include "mbiter.h" |
29 | #include "mbchar.h" | 28 | #include "mbchar.h" |
30 | #include "mbswidth.h" | 29 | #include "mbswidth.h" | ... | ... |
... | @@ -15,8 +15,6 @@ | ... | @@ -15,8 +15,6 @@ |
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | 16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ |
17 | 17 | ||
18 | /* Parse traditional MH options. */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | 18 | #ifdef HAVE_CONFIG_H |
21 | # include <config.h> | 19 | # include <config.h> |
22 | #endif | 20 | #endif |
... | @@ -24,197 +22,224 @@ | ... | @@ -24,197 +22,224 @@ |
24 | #include <stdio.h> | 22 | #include <stdio.h> |
25 | #include <stdlib.h> | 23 | #include <stdlib.h> |
26 | #include <string.h> | 24 | #include <string.h> |
27 | #include <mh_getopt.h> | 25 | #include "mh.h" |
26 | #include <mailutils/stream.h> | ||
27 | #include <mailutils/wordsplit.h> | ||
28 | #include <mailutils/io.h> | 28 | #include <mailutils/io.h> |
29 | 29 | ||
30 | static int mh_optind = 1; | 30 | struct getopt_data |
31 | static char *mh_optarg; | 31 | { |
32 | static char *mh_optptr; | 32 | char *extra_doc; |
33 | }; | ||
33 | 34 | ||
34 | void (*mh_help_hook) (); | 35 | static void |
36 | mh_extra_help_hook (struct mu_parseopt *po, mu_stream_t stream) | ||
37 | { | ||
38 | struct getopt_data *data = po->po_data; | ||
39 | mu_stream_printf (stream, "%s\n", _(data->extra_doc)); | ||
40 | } | ||
35 | 41 | ||
36 | int | 42 | static void |
37 | mh_getopt (int argc, char **argv, struct mh_option *mh_opt, const char *doc) | 43 | augment_argv (int *pargc, char ***pargv) |
38 | { | 44 | { |
39 | struct mh_option *p; | 45 | int argc; |
40 | int optlen; | 46 | char **argv; |
47 | int i, j; | ||
48 | struct mu_wordsplit ws; | ||
49 | char const *val = mh_global_profile_get (mu_program_name, NULL); | ||
41 | 50 | ||
42 | if (mh_optind >= argc || argv[mh_optind] == NULL) | 51 | if (!val) |
43 | return EOF; | 52 | return; |
44 | mh_optptr = argv[mh_optind]; | ||
45 | 53 | ||
46 | if (mh_optptr[0] == '+') | 54 | if (mu_wordsplit (val, &ws, MU_WRDSF_DEFFLAGS)) |
47 | { | 55 | { |
48 | mh_optarg = mh_optptr + 1; | 56 | mu_error (_("cannot split line `%s': %s"), val, |
49 | mh_optind++; | 57 | mu_wordsplit_strerror (&ws)); |
50 | return '+'; | 58 | exit (1); |
51 | } | 59 | } |
52 | 60 | ||
53 | if (mh_optptr[0] != '-' || mh_optptr[1] == '-') | 61 | argc = *pargc + ws.ws_wordc; |
54 | { | 62 | argv = calloc (argc + 1, sizeof *argv); |
55 | mh_optind++; | 63 | if (!argv) |
56 | return 0; | 64 | mh_err_memory (1); |
57 | } | ||
58 | 65 | ||
59 | if (strcmp (mh_optptr, "-version") == 0) | 66 | i = 0; |
60 | mu_asprintf (&argv[mh_optind], "--version"); | 67 | argv[i++] = (*pargv)[0]; |
61 | else | 68 | for (j = 0; j < ws.ws_wordc; i++, j++) |
62 | { | 69 | argv[i] = ws.ws_wordv[j]; |
63 | int negation = 0; | 70 | for (j = 1; i < argc; i++, j++) |
71 | argv[i] = (*pargv)[j]; | ||
72 | argv[i] = NULL; | ||
64 | 73 | ||
65 | optlen = strlen (mh_optptr+1); | 74 | ws.ws_wordc = 0; |
66 | for (p = mh_opt; p->opt; p++) | 75 | mu_wordsplit_free (&ws); |
67 | { | 76 | |
68 | if (p->match_len <= optlen | 77 | *pargc = argc; |
69 | && memcmp (mh_optptr+1, p->opt, optlen) == 0) | 78 | *pargv = argv; |
70 | break; | 79 | } |
71 | if (p->flags == MH_OPT_BOOL | 80 | |
72 | && optlen > 2 | 81 | static void |
73 | && memcmp (mh_optptr+1, "no", 2) == 0 | 82 | process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po) |
74 | && strlen (p->opt) >= optlen-2 | 83 | { |
75 | && memcmp (mh_optptr+3, p->opt, optlen-2) == 0) | 84 | int i, j; |
85 | int argc = *pargc; | ||
86 | struct mu_option *opt; | ||
87 | |||
88 | /* Find folder option */ | ||
89 | for (i = 0; ; i++) | ||
76 | { | 90 | { |
77 | negation = 1; | 91 | if (!po->po_optv[i]) |
92 | return; /* Nothing to do */ | ||
93 | if (MU_OPTION_IS_VALID_LONG_OPTION (po->po_optv[i]) | ||
94 | && strcmp (po->po_optv[i]->opt_long, "folder") == 0) | ||
78 | break; | 95 | break; |
79 | } | 96 | } |
80 | } | 97 | opt = po->po_optv[i]; |
81 | 98 | ||
82 | if (p->opt) | 99 | for (i = j = 0; i < argc; i++) |
83 | { | 100 | { |
84 | char *longopt = p->opt; | 101 | if (argv[i][0] == '+') |
85 | switch (p->flags) | ||
86 | { | 102 | { |
87 | case MH_OPT_BOOL: | 103 | opt->opt_set (po, opt, argv[i] + 1); |
88 | mh_optarg = negation ? "no" : "yes"; | ||
89 | mu_asprintf (&argv[mh_optind], "--%s=%s", longopt, mh_optarg); | ||
90 | break; | ||
91 | |||
92 | case MH_OPT_ARG: | ||
93 | mu_asprintf (&argv[mh_optind], "--%s", longopt); | ||
94 | mh_optarg = argv[++mh_optind]; | ||
95 | break; | ||
96 | |||
97 | default: | ||
98 | mu_asprintf (&argv[mh_optind], "--%s", longopt); | ||
99 | mh_optarg = NULL; | ||
100 | } | ||
101 | mh_optind++; | ||
102 | return 1; | ||
103 | } | ||
104 | else if (!strcmp (mh_optptr+1, "help")) | ||
105 | { | ||
106 | mh_help (mh_opt, doc); | ||
107 | exit (1); | ||
108 | } | 104 | } |
109 | else | 105 | else |
110 | mh_optind++; | 106 | argv[j++] = argv[i]; |
111 | } | 107 | } |
112 | return '?'; | 108 | argv[j] = NULL; |
109 | *pargc = j; | ||
113 | } | 110 | } |
114 | 111 | ||
115 | void | 112 | static void |
116 | mh_argv_preproc (int argc, char **argv, struct mh_argp_data *data) | 113 | set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
117 | { | 114 | { |
118 | mh_optind = 1; | 115 | mh_set_current_folder (arg); |
119 | while (mh_getopt (argc, argv, data->mh_option, data->doc) != EOF) | ||
120 | ; | ||
121 | } | 116 | } |
122 | 117 | ||
118 | static struct mu_option folder_option[] = { | ||
119 | { "folder", 0, NULL, MU_OPTION_DEFAULT, | ||
120 | N_("set current folder"), | ||
121 | mu_c_string, NULL, set_folder }, | ||
122 | MU_OPTION_END | ||
123 | }; | ||
124 | |||
123 | void | 125 | void |
124 | mh_help (struct mh_option *mh_opt, const char *doc) | 126 | mh_getopt (int *pargc, char ***pargv, struct mu_option *options, |
127 | int mhflags, | ||
128 | char *argdoc, char *progdoc, char *extradoc) | ||
125 | { | 129 | { |
126 | struct mh_option *p; | 130 | int argc = *pargc; |
127 | 131 | char **argv = *pargv; | |
128 | printf (_("Compatibility syntax:\n")); | 132 | struct mu_parseopt po; |
129 | printf (_("%s [switches] %s\n"), mu_program_name, doc); | 133 | struct mu_option *optv[3]; |
130 | printf (_(" switches are:\n")); | 134 | struct getopt_data getopt_data; |
135 | char const *args[2]; | ||
136 | int flags = MU_PARSEOPT_SINGLE_DASH | MU_PARSEOPT_IMMEDIATE; | ||
137 | int i; | ||
138 | |||
139 | po.po_negation = "no"; | ||
140 | flags |= MU_PARSEOPT_NEGATION; | ||
141 | |||
142 | if (argdoc) | ||
143 | { | ||
144 | args[0] = argdoc; | ||
145 | args[1] = NULL; | ||
146 | po.po_prog_args = args; | ||
147 | flags |= MU_PARSEOPT_PROG_ARGS; | ||
148 | } | ||
149 | if (progdoc) | ||
150 | { | ||
151 | po.po_prog_doc = progdoc; | ||
152 | flags |= MU_PARSEOPT_PROG_DOC; | ||
153 | } | ||
131 | 154 | ||
132 | for (p = mh_opt; p->opt; p++) | 155 | getopt_data.extra_doc = extradoc; |
156 | if (extradoc) | ||
133 | { | 157 | { |
134 | int len = strlen (p->opt); | 158 | po.po_help_hook = mh_extra_help_hook; |
135 | 159 | flags |= MU_PARSEOPT_HELP_HOOK; | |
136 | printf (" -"); | 160 | } |
137 | if (p->flags == MH_OPT_BOOL) | 161 | |
138 | printf ("[no]"); | 162 | po.po_data = &getopt_data; |
139 | if (len > p->match_len) | 163 | flags |= MU_PARSEOPT_DATA; |
140 | printf ("(%*.*s)%s", | 164 | |
141 | (int) p->match_len, (int) p->match_len, p->opt, | 165 | po.po_exit_error = 1; |
142 | p->opt + p->match_len); | 166 | flags |= MU_PARSEOPT_EXIT_ERROR; |
143 | else | 167 | |
144 | printf ("%s", p->opt); | 168 | po.po_package_name = PACKAGE_NAME; |
169 | flags |= MU_PARSEOPT_PACKAGE_NAME; | ||
170 | |||
171 | po.po_package_url = PACKAGE_URL; | ||
172 | flags |= MU_PARSEOPT_PACKAGE_URL; | ||
173 | |||
174 | po.po_bug_address = PACKAGE_BUGREPORT; | ||
175 | flags |= MU_PARSEOPT_BUG_ADDRESS; | ||
176 | |||
177 | //po.po_extra_info = gnu_general_help_url; | ||
178 | //flags |= MU_PARSEOPT_EXTRA_INFO; | ||
179 | |||
180 | mu_set_program_name (argv[0]); | ||
181 | mh_init (); | ||
182 | augment_argv (&argc, &argv); | ||
145 | 183 | ||
146 | if (p->flags == MH_OPT_ARG) | 184 | i = 0; |
147 | printf (" %s", p->arg); | 185 | if (mhflags & MH_GETOPT_DEFAULT_FOLDER) |
148 | printf ("\n"); | 186 | optv[i++] = folder_option; |
187 | optv[i++] = options; | ||
188 | optv[i] = NULL; | ||
189 | |||
190 | if (mu_parseopt (&po, argc, argv, optv, flags)) | ||
191 | exit (po.po_exit_error); | ||
192 | |||
193 | argc -= po.po_arg_start; | ||
194 | argv += po.po_arg_start; | ||
195 | |||
196 | process_folder_arg (&argc, argv, &po); | ||
197 | |||
198 | if (!argdoc && argc) | ||
199 | { | ||
200 | mu_error (_("Extra arguments")); | ||
201 | exit (1); | ||
149 | } | 202 | } |
150 | if (mh_help_hook) | ||
151 | mh_help_hook (); | ||
152 | printf (" -help\n"); | ||
153 | printf (" -version\n"); | ||
154 | printf (_("\nPlease use GNU long options instead.\n" | ||
155 | "Run %s --help for more info on these.\n"), | ||
156 | mu_program_name); | ||
157 | } | ||
158 | 203 | ||
204 | *pargc = argc; | ||
205 | *pargv = argv; | ||
206 | |||
207 | mh_init2 (); | ||
208 | } | ||
159 | 209 | ||
160 | static int | 210 | void |
161 | optcmp (const void *a, const void *b) | 211 | mh_opt_notimpl (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
162 | { | 212 | { |
163 | struct mh_option const *opta = a, *optb = b; | 213 | mu_error (_("option is not yet implemented: %s"), opt->opt_long); |
164 | return strcmp (opta->opt, optb->opt); | 214 | exit (1); |
165 | } | 215 | } |
166 | 216 | ||
167 | void | 217 | void |
168 | mh_option_init (struct mh_option *opt) | 218 | mh_opt_notimpl_warning (struct mu_parseopt *po, struct mu_option *opt, |
219 | char const *arg) | ||
169 | { | 220 | { |
170 | size_t count, i; | 221 | mu_error (_("ignoring not implemented option %s"), opt->opt_long); |
171 | 222 | } | |
172 | /* Count number of elements and initialize minimum abbreviation | ||
173 | lengths to 1. */ | ||
174 | for (count = 0; opt[count].opt; count++) | ||
175 | opt[count].match_len = 1; | ||
176 | /* Sort them alphabetically */ | ||
177 | qsort (opt, count, sizeof (opt[0]), optcmp); | ||
178 | /* Determine minimum abbreviations */ | ||
179 | for (i = 0; i < count; i++) | ||
180 | { | ||
181 | const char *sample = opt[i].opt; | ||
182 | size_t sample_len = strlen (sample); | ||
183 | size_t minlen = opt[i].match_len; | ||
184 | size_t j; | ||
185 | 223 | ||
186 | for (j = i + 1; j < count; j++) | 224 | void |
187 | { | 225 | mh_opt_clear_string (struct mu_parseopt *po, struct mu_option *opt, |
188 | size_t len = strlen (opt[j].opt); | 226 | char const *arg) |
189 | if (len >= minlen && memcmp (opt[j].opt, sample, minlen) == 0) | 227 | { |
190 | do | 228 | char **sptr = opt->opt_ptr; |
191 | { | 229 | free (*sptr); |
192 | minlen++; | 230 | *sptr = NULL; |
193 | if (minlen <= strlen (opt[j].opt)) | ||
194 | opt[j].match_len = minlen; | ||
195 | if (minlen == sample_len) | ||
196 | break; | ||
197 | } | ||
198 | while (len >= minlen && memcmp (opt[j].opt, sample, minlen) == 0); | ||
199 | else if (opt[j].opt[0] == sample[0]) | ||
200 | opt[j].match_len = minlen; | ||
201 | else | ||
202 | break; | ||
203 | } | ||
204 | if (minlen <= sample_len) | ||
205 | opt[i].match_len = minlen; | ||
206 | } | ||
207 | } | 231 | } |
208 | 232 | ||
209 | void | 233 | void |
210 | mh_opt_notimpl (const char *name) | 234 | mh_opt_find_file (struct mu_parseopt *po, struct mu_option *opt, |
235 | char const *arg) | ||
211 | { | 236 | { |
212 | mu_error (_("option is not yet implemented: %s"), name); | 237 | mh_find_file (arg, opt->opt_ptr); |
213 | exit (1); | ||
214 | } | 238 | } |
215 | 239 | ||
216 | void | 240 | void |
217 | mh_opt_notimpl_warning (const char *name) | 241 | mh_opt_read_formfile (struct mu_parseopt *po, struct mu_option *opt, |
242 | char const *arg) | ||
218 | { | 243 | { |
219 | mu_error (_("ignoring not implemented option %s"), name); | 244 | mh_read_formfile (arg, opt->opt_ptr); |
220 | } | 245 | } | ... | ... |
... | @@ -16,198 +16,24 @@ | ... | @@ -16,198 +16,24 @@ |
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | 16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ |
17 | 17 | ||
18 | #include <mailutils/nls.h> | 18 | #include <mailutils/nls.h> |
19 | #include "argp.h" | 19 | #include <mailutils/opt.h> |
20 | #include "mailutils/libargp.h" | ||
21 | 20 | ||
22 | #define MH_OPT_BOOL 1 | 21 | #define MH_GETOPT_DEFAULT_FOLDER 0x1 |
23 | #define MH_OPT_ARG 2 | ||
24 | 22 | ||
25 | struct mh_option | 23 | void mh_getopt (int *pargc, char ***pargv, struct mu_option *options, |
26 | { | 24 | int flags, |
27 | char *opt; | 25 | char *argdoc, char *progdoc, char *extradoc); |
28 | int flags; | ||
29 | char *arg; | ||
30 | size_t match_len; | ||
31 | }; | ||
32 | |||
33 | struct mh_argp_data | ||
34 | { | ||
35 | struct mh_option *mh_option; | ||
36 | argp_parser_t handler; | ||
37 | int errind; | ||
38 | void *closure; | ||
39 | char *doc; | ||
40 | }; | ||
41 | |||
42 | enum mh_arg { | ||
43 | ARG_ADD = 256, | ||
44 | ARG_AFTER, | ||
45 | ARG_ALIAS, | ||
46 | ARG_ALL, | ||
47 | ARG_AND, | ||
48 | ARG_ANNOTATE, | ||
49 | ARG_APOP, | ||
50 | ARG_AUDIT, | ||
51 | ARG_AUTO, | ||
52 | ARG_BEFORE, | ||
53 | ARG_BELL, | ||
54 | ARG_BUILD, | ||
55 | ARG_CC, | ||
56 | ARG_CFLAGS, | ||
57 | ARG_CHANGECUR, | ||
58 | ARG_CHARSET, | ||
59 | ARG_CHECK, | ||
60 | ARG_CHUNKSIZE, | ||
61 | ARG_CLEAR, | ||
62 | ARG_COMPAT, | ||
63 | ARG_COMPONENT, | ||
64 | ARG_COMPOSE, | ||
65 | ARG_CREATE, | ||
66 | ARG_DATE, | ||
67 | ARG_DATEFIELD, | ||
68 | ARG_DEBUG, | ||
69 | ARG_DELETE, | ||
70 | ARG_DRAFT, | ||
71 | ARG_DRAFTFOLDER, | ||
72 | ARG_DRAFTMESSAGE, | ||
73 | ARG_DRY_RUN, | ||
74 | ARG_DUMP, | ||
75 | ARG_EDITOR, | ||
76 | ARG_FAST, | ||
77 | ARG_FCC, | ||
78 | ARG_FILE, | ||
79 | ARG_FILTER, | ||
80 | ARG_FOLDER, | ||
81 | ARG_FORM, | ||
82 | ARG_FORMAT, | ||
83 | ARG_FORWARD, | ||
84 | ARG_FROM, | ||
85 | ARG_GROUP, | ||
86 | ARG_HEADER, | ||
87 | ARG_HOST, | ||
88 | ARG_INPLACE, | ||
89 | ARG_INTERACTIVE, | ||
90 | ARG_LANG, | ||
91 | ARG_LBRACE, | ||
92 | ARG_LENGTH, | ||
93 | ARG_LIMIT, | ||
94 | ARG_LINK, | ||
95 | ARG_LIST, | ||
96 | ARG_MIME, | ||
97 | ARG_MOREPROC, | ||
98 | ARG_MOVETO, | ||
99 | ARG_MSGID, | ||
100 | ARG_NOALIAS, | ||
101 | ARG_NOAPOP, | ||
102 | ARG_NOAUDIT, | ||
103 | ARG_NOAUTO, | ||
104 | ARG_NOBELL, | ||
105 | ARG_NOCC, | ||
106 | ARG_NOCHANGECUR, | ||
107 | ARG_NOCHECK, | ||
108 | ARG_NOCLEAR, | ||
109 | ARG_NOCOMPOSE, | ||
110 | ARG_NOCREATE, | ||
111 | ARG_NODATE, | ||
112 | ARG_NODATEFIELD, | ||
113 | ARG_NODRAFTFOLDER, | ||
114 | ARG_NOEDIT, | ||
115 | ARG_NOFAST, | ||
116 | ARG_NOFILTER, | ||
117 | ARG_NOFORMAT, | ||
118 | ARG_NOFORWARD, | ||
119 | ARG_NOHEADER, | ||
120 | ARG_NOHEADERS, | ||
121 | ARG_NOINPLACE, | ||
122 | ARG_NOINTERACTIVE, | ||
123 | ARG_NOLIMIT, | ||
124 | ARG_NOLIST, | ||
125 | ARG_NOMIME, | ||
126 | ARG_NOMOREPROC, | ||
127 | ARG_NOMSGID, | ||
128 | ARG_NONOTIFY, | ||
129 | ARG_NOPAUSE, | ||
130 | ARG_NOPUBLIC, | ||
131 | ARG_NOPUSH, | ||
132 | ARG_NOQUIET, | ||
133 | ARG_NOREALSIZE, | ||
134 | ARG_NORECURSIVE, | ||
135 | ARG_NOREVERSE, | ||
136 | ARG_NORMALIZE, | ||
137 | ARG_NOSERIALONLY, | ||
138 | ARG_NOSHOW, | ||
139 | ARG_NOSHOWPROC, | ||
140 | ARG_NOSTORE, | ||
141 | ARG_NOT, | ||
142 | ARG_NOTEXTFIELD, | ||
143 | ARG_NOTIFY, | ||
144 | ARG_NOTOTAL, | ||
145 | ARG_NOTRUNCATE, | ||
146 | ARG_NOUSE, | ||
147 | ARG_NOVERBOSE, | ||
148 | ARG_NOWATCH, | ||
149 | ARG_NOWHATNOWPROC, | ||
150 | ARG_NOZERO, | ||
151 | ARG_NUMFIELD, | ||
152 | ARG_OR, | ||
153 | ARG_PACK, | ||
154 | ARG_PART, | ||
155 | ARG_PATTERN, | ||
156 | ARG_PAUSE, | ||
157 | ARG_POP, | ||
158 | ARG_PRESERVE, | ||
159 | ARG_PRINT, | ||
160 | ARG_PROMPT, | ||
161 | ARG_PUBLIC, | ||
162 | ARG_PUSH, | ||
163 | ARG_QUERY, | ||
164 | ARG_QUIET, | ||
165 | ARG_RBRACE, | ||
166 | ARG_REALSIZE, | ||
167 | ARG_RECURSIVE, | ||
168 | ARG_REORDER, | ||
169 | ARG_REVERSE, | ||
170 | ARG_SCRIPT, | ||
171 | ARG_SEQUENCE, | ||
172 | ARG_SERIALONLY, | ||
173 | ARG_SHOW, | ||
174 | ARG_SHOWPROC, | ||
175 | ARG_SOURCE, | ||
176 | ARG_SPLIT, | ||
177 | ARG_STORE, | ||
178 | ARG_SUBJECT, | ||
179 | ARG_TEXT, | ||
180 | ARG_TEXTFIELD, | ||
181 | ARG_TO, | ||
182 | ARG_TOTAL, | ||
183 | ARG_TRUNCATE, | ||
184 | ARG_TYPE, | ||
185 | ARG_USE, | ||
186 | ARG_USER, | ||
187 | ARG_VERBOSE, | ||
188 | ARG_WATCH, | ||
189 | ARG_WHATNOWPROC, | ||
190 | ARG_WIDTH, | ||
191 | ARG_ZERO | ||
192 | }; | ||
193 | |||
194 | extern void (*mh_help_hook) (void); | ||
195 | 26 | ||
196 | void mh_option_init (struct mh_option *opt); | 27 | void mh_opt_notimpl (struct mu_parseopt *po, struct mu_option *opt, |
28 | char const *arg); | ||
29 | void mh_opt_notimpl_warning (struct mu_parseopt *po, struct mu_option *opt, | ||
30 | char const *arg); | ||
31 | void mh_opt_clear_string (struct mu_parseopt *po, struct mu_option *opt, | ||
32 | char const *arg); | ||
197 | 33 | ||
198 | void mh_argp_init (void); | 34 | void mh_opt_find_file (struct mu_parseopt *po, struct mu_option *opt, |
199 | void mh_argv_preproc (int argc, char **argv, struct mh_argp_data *data); | 35 | char const *arg); |
200 | int mh_getopt (int argc, char **argv, struct mh_option *mh_opt, const char *doc); | 36 | void mh_opt_read_formfile (struct mu_parseopt *po, struct mu_option *opt, |
201 | int mh_argp_parse (int *argc, char **argv[], | 37 | char const *arg); |
202 | int flags, | ||
203 | struct argp_option *option, | ||
204 | struct mh_option *mh_option, | ||
205 | char *argp_doc, char *doc, | ||
206 | argp_parser_t handler, | ||
207 | void *closure, int *index); | ||
208 | 38 | ||
209 | void mh_help (struct mh_option *mh_option, const char *doc); | ||
210 | void mh_license (const char *name); | ||
211 | 39 | ||
212 | void mh_opt_notimpl (const char *name); | ||
213 | void mh_opt_notimpl_warning (const char *name); | ... | ... |
... | @@ -21,48 +21,15 @@ | ... | @@ -21,48 +21,15 @@ |
21 | #include <sys/stat.h> | 21 | #include <sys/stat.h> |
22 | #include <unistd.h> | 22 | #include <unistd.h> |
23 | 23 | ||
24 | static char doc[] = N_("GNU MH mhl")"\v" | 24 | static char prog_doc[] = N_("GNU MH mhl"); |
25 | N_("Use -help to obtain the list of traditional MH options."); | ||
26 | static char args_doc[] = N_("[FILE [FILE...]]"); | 25 | static char args_doc[] = N_("[FILE [FILE...]]"); |
27 | 26 | ||
28 | /* GNU options */ | 27 | static int bell_option; |
29 | static struct argp_option options[] = { | 28 | static int clear_option; |
30 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
31 | N_("specify folder to operate upon")}, | ||
32 | { "bell", ARG_BELL, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
33 | N_("ring the bell at the end of each output page") }, | ||
34 | {"nobell", ARG_NOBELL, NULL, OPTION_HIDDEN, "" }, | ||
35 | { "clear", ARG_CLEAR, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
36 | N_("clear the screen after each page of output")}, | ||
37 | {"noclear", ARG_NOCLEAR, NULL, OPTION_HIDDEN, "" }, | ||
38 | {"form", ARG_FORM, N_("FILE"), 0, | ||
39 | N_("read format from given file")}, | ||
40 | {"width", ARG_WIDTH, N_("NUMBER"), 0, | ||
41 | N_("set output width")}, | ||
42 | {"length", ARG_LENGTH, N_("NUMBER"), 0, | ||
43 | N_("set output screen length")}, | ||
44 | {"moreproc", ARG_MOREPROC, N_("PROG"), 0, | ||
45 | N_("use given PROG instead of the default") }, | ||
46 | {"nomoreproc", ARG_NOMOREPROC, NULL, 0, | ||
47 | N_("disable use of moreproc program") }, | ||
48 | { NULL } | ||
49 | }; | ||
50 | |||
51 | /* Traditional MH options */ | ||
52 | struct mh_option mh_option[] = { | ||
53 | { "bell", MH_OPT_BOOL }, | ||
54 | { "clear", MH_OPT_BOOL }, | ||
55 | { "form", MH_OPT_ARG, "formatfile"}, | ||
56 | { "width", MH_OPT_ARG, "number"}, | ||
57 | { "length", MH_OPT_ARG, "number"}, | ||
58 | { "moreproc", MH_OPT_ARG, "program"}, | ||
59 | { "nomoreproc" }, | ||
60 | { NULL } | ||
61 | }; | ||
62 | 29 | ||
63 | static int interactive; /* Using interactive output */ | 30 | static int interactive; /* Using interactive output */ |
64 | static int mhl_fmt_flags; /* MHL format flags. Controlled by --bell | 31 | static int mhl_fmt_flags; /* MHL format flags. Controlled by -bell |
65 | and --clear */ | 32 | and -clear */ |
66 | static int length = 40; /* Length of output page */ | 33 | static int length = 40; /* Length of output page */ |
67 | static int width = 80; /* Width of output page */ | 34 | static int width = 80; /* Width of output page */ |
68 | static char *formfile = MHLIBDIR "/mhl.format"; | 35 | static char *formfile = MHLIBDIR "/mhl.format"; |
... | @@ -71,68 +38,30 @@ static int nomoreproc; | ... | @@ -71,68 +38,30 @@ static int nomoreproc; |
71 | 38 | ||
72 | static mu_list_t format; | 39 | static mu_list_t format; |
73 | 40 | ||
74 | static error_t | 41 | static struct mu_option options[] = { |
75 | opt_handler (int key, char *arg, struct argp_state *state) | 42 | { "bell", 0, NULL, MU_OPTION_DEFAULT, |
76 | { | 43 | N_("ring the bell at the end of each output page"), |
77 | switch (key) | 44 | mu_c_bool, &bell_option }, |
78 | { | 45 | { "clear", 0, NULL, MU_OPTION_DEFAULT, |
79 | case ARG_FOLDER: | 46 | N_("clear the screen after each page of output"), |
80 | mh_set_current_folder (arg); | 47 | mu_c_bool, &clear_option }, |
81 | break; | 48 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, |
82 | 49 | N_("read format from given file"), | |
83 | case ARG_BELL: | 50 | mu_c_string, &formfile, mh_opt_find_file }, |
84 | if (is_true (arg)) | 51 | { "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT, |
85 | mhl_fmt_flags |= MHL_BELL; | 52 | N_("set output width"), |
86 | break; | 53 | mu_c_int, &width }, |
87 | 54 | { "length", 0, N_("NUMBER"), MU_OPTION_DEFAULT, | |
88 | case ARG_NOBELL: | 55 | N_("set output screen length"), |
89 | mhl_fmt_flags &= ~MHL_BELL; | 56 | mu_c_int, &length }, |
90 | break; | 57 | { "moreproc", 0, N_("PROG"), MU_OPTION_DEFAULT, |
91 | 58 | N_("use given PROG instead of the default"), | |
92 | case ARG_CLEAR: | 59 | mu_c_string, &moreproc }, |
93 | if (is_true (arg)) | 60 | { "nomoreproc", 0, NULL, MU_OPTION_DEFAULT, |
94 | mhl_fmt_flags |= MHL_CLEARSCREEN; | 61 | N_("disable use of moreproc program"), |
95 | break; | 62 | mu_c_bool, &nomoreproc }, |
96 | 63 | MU_OPTION_END | |
97 | case ARG_NOCLEAR: | 64 | }; |
98 | mhl_fmt_flags &= ~MHL_CLEARSCREEN; | ||
99 | break; | ||
100 | |||
101 | case ARG_FORM: | ||
102 | mh_find_file (arg, &formfile); | ||
103 | break; | ||
104 | |||
105 | case ARG_WIDTH: | ||
106 | width = strtoul (arg, NULL, 0); | ||
107 | if (!width) | ||
108 | { | ||
109 | argp_error (state, _("invalid width")); | ||
110 | exit (1); | ||
111 | } | ||
112 | break; | ||
113 | |||
114 | case ARG_LENGTH: | ||
115 | length = strtoul (arg, NULL, 0); | ||
116 | if (!length) | ||
117 | { | ||
118 | argp_error (state, _("invalid length")); | ||
119 | exit (1); | ||
120 | } | ||
121 | break; | ||
122 | |||
123 | case ARG_MOREPROC: | ||
124 | moreproc = arg; | ||
125 | break; | ||
126 | |||
127 | case ARG_NOMOREPROC: | ||
128 | nomoreproc = 1; | ||
129 | break; | ||
130 | |||
131 | default: | ||
132 | return ARGP_ERR_UNKNOWN; | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | 65 | ||
137 | static mu_stream_t | 66 | static mu_stream_t |
138 | open_output () | 67 | open_output () |
... | @@ -205,23 +134,33 @@ list_message (char *name, mu_stream_t output) | ... | @@ -205,23 +134,33 @@ list_message (char *name, mu_stream_t output) |
205 | int | 134 | int |
206 | main (int argc, char **argv) | 135 | main (int argc, char **argv) |
207 | { | 136 | { |
208 | int index; | ||
209 | mu_stream_t output; | 137 | mu_stream_t output; |
210 | 138 | ||
211 | interactive = isatty (1) && isatty (0); | 139 | interactive = isatty (1) && isatty (0); |
212 | 140 | ||
213 | MU_APP_INIT_NLS (); | 141 | MU_APP_INIT_NLS (); |
214 | mh_argp_init (); | 142 | |
215 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 143 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
216 | opt_handler, NULL, &index); | 144 | args_doc, prog_doc, NULL); |
145 | |||
146 | if (bell_option == -1) | ||
147 | /* use default */; | ||
148 | else if (bell_option) | ||
149 | mhl_fmt_flags |= MHL_BELL; | ||
150 | else | ||
151 | mhl_fmt_flags &= ~MHL_BELL; | ||
152 | |||
153 | if (clear_option == -1) | ||
154 | /* use default */; | ||
155 | else if (clear_option) | ||
156 | mhl_fmt_flags |= MHL_CLEARSCREEN; | ||
157 | else | ||
158 | mhl_fmt_flags &= ~MHL_CLEARSCREEN; | ||
217 | 159 | ||
218 | format = mhl_format_compile (formfile); | 160 | format = mhl_format_compile (formfile); |
219 | if (!format) | 161 | if (!format) |
220 | exit (1); | 162 | exit (1); |
221 | 163 | ||
222 | argc -= index; | ||
223 | argv += index; | ||
224 | |||
225 | if (argc == 0) | 164 | if (argc == 0) |
226 | nomoreproc = 1; | 165 | nomoreproc = 1; |
227 | 166 | ... | ... |
... | @@ -26,46 +26,9 @@ | ... | @@ -26,46 +26,9 @@ |
26 | #include <time.h> | 26 | #include <time.h> |
27 | #include <mailutils/observer.h> | 27 | #include <mailutils/observer.h> |
28 | 28 | ||
29 | static char doc[] = N_("GNU MH scan")"\v" | 29 | static char progdoc[] = N_("GNU MH scan"); |
30 | N_("Use -help to obtain the list of traditional MH options."); | ||
31 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); | 30 | static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); |
32 | 31 | ||
33 | /* GNU options */ | ||
34 | static struct argp_option options[] = { | ||
35 | {"folder", ARG_FOLDER, N_("FOLDER"), 0, | ||
36 | N_("specify folder to scan")}, | ||
37 | {"clear", ARG_CLEAR, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
38 | N_("clear screen after displaying the list")}, | ||
39 | {"noclear", ARG_NOCLEAR, NULL, OPTION_HIDDEN, ""}, | ||
40 | {"form", ARG_FORM, N_("FILE"), 0, | ||
41 | N_("read format from given file")}, | ||
42 | {"format", ARG_FORMAT, N_("FORMAT"), 0, | ||
43 | N_("use this format string")}, | ||
44 | {"header", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
45 | N_("display header")}, | ||
46 | {"width", ARG_WIDTH, N_("NUMBER"), 0, | ||
47 | N_("set output width")}, | ||
48 | {"reverse", ARG_REVERSE, N_("BOOL"), OPTION_ARG_OPTIONAL, | ||
49 | N_("list messages in reverse order")}, | ||
50 | {"noreverse", ARG_NOREVERSE, NULL, OPTION_HIDDEN, ""}, | ||
51 | {"file", ARG_FILE, N_("FILE"), 0, | ||
52 | N_("[not yet implemented]")}, | ||
53 | |||
54 | { 0 } | ||
55 | }; | ||
56 | |||
57 | /* Traditional MH options */ | ||
58 | struct mh_option mh_option[] = { | ||
59 | { "clear", MH_OPT_BOOL }, | ||
60 | { "form", MH_OPT_ARG, "formatfile" }, | ||
61 | { "format", MH_OPT_ARG, "string" }, | ||
62 | { "header", MH_OPT_BOOL }, | ||
63 | { "width", MH_OPT_ARG, "number" }, | ||
64 | { "reverse", MH_OPT_BOOL }, | ||
65 | { "file", MH_OPT_ARG, "file" }, | ||
66 | { NULL } | ||
67 | }; | ||
68 | |||
69 | static int clear; | 32 | static int clear; |
70 | static char *format_str = mh_list_format; | 33 | static char *format_str = mh_list_format; |
71 | 34 | ||
... | @@ -77,66 +40,41 @@ static mh_format_t format; | ... | @@ -77,66 +40,41 @@ static mh_format_t format; |
77 | 40 | ||
78 | static mu_msgset_t msgset; | 41 | static mu_msgset_t msgset; |
79 | 42 | ||
80 | static int list_message (size_t num, mu_message_t msg, void *data); | 43 | static void |
81 | void print_header (mu_mailbox_t mbox); | 44 | form_handler (struct mu_parseopt *po, struct mu_option *opt, char const *arg) |
82 | void clear_screen (void); | ||
83 | |||
84 | static error_t | ||
85 | opt_handler (int key, char *arg, struct argp_state *state) | ||
86 | { | 45 | { |
87 | switch (key) | ||
88 | { | ||
89 | case ARG_FOLDER: | ||
90 | mh_set_current_folder (arg); | ||
91 | break; | ||
92 | |||
93 | case ARG_CLEAR: | ||
94 | clear = is_true(arg); | ||
95 | break; | ||
96 | |||
97 | case ARG_NOCLEAR: | ||
98 | clear = 0; | ||
99 | break; | ||
100 | |||
101 | case ARG_FORM: | ||
102 | if (mh_read_formfile (arg, &format_str)) | 46 | if (mh_read_formfile (arg, &format_str)) |
103 | exit (1); | 47 | exit (1); |
104 | break; | 48 | } |
105 | |||
106 | case ARG_FORMAT: | ||
107 | format_str = arg; | ||
108 | break; | ||
109 | |||
110 | case ARG_HEADER: | ||
111 | header = is_true(arg); | ||
112 | break; | ||
113 | |||
114 | case ARG_WIDTH: | ||
115 | width = strtoul (arg, NULL, 0); | ||
116 | if (!width) | ||
117 | { | ||
118 | argp_error (state, _("invalid width")); | ||
119 | exit (1); | ||
120 | } | ||
121 | break; | ||
122 | |||
123 | case ARG_REVERSE: | ||
124 | reverse = is_true(arg); | ||
125 | break; | ||
126 | |||
127 | case ARG_NOREVERSE: | ||
128 | reverse = 0; | ||
129 | break; | ||
130 | 49 | ||
131 | case ARG_FILE: | 50 | static struct mu_option options[] = { |
132 | mh_opt_notimpl ("-file"); | 51 | { "clear", 0, NULL, MU_OPTION_DEFAULT, |
133 | break; | 52 | N_("clear screen after displaying the list"), |
53 | mu_c_bool, &clear }, | ||
54 | { "form", 0, N_("FILE"), MU_OPTION_DEFAULT, | ||
55 | N_("read format from given file"), | ||
56 | mu_c_string, NULL, form_handler }, | ||
57 | { "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT, | ||
58 | N_("use this format string"), | ||
59 | mu_c_string, &format_str }, | ||
60 | { "header", 0, NULL, MU_OPTION_DEFAULT, | ||
61 | N_("display header"), | ||
62 | mu_c_bool, &header }, | ||
63 | { "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT, | ||
64 | N_("set output width"), | ||
65 | mu_c_int, &width }, | ||
66 | { "reverse", 0, NULL, MU_OPTION_DEFAULT, | ||
67 | N_("list messages in reverse order"), | ||
68 | mu_c_bool, &reverse }, | ||
69 | { "file", 0, N_("FILE"), MU_OPTION_HIDDEN, | ||
70 | N_("[not yet implemented]"), | ||
71 | mu_c_string, NULL, mh_opt_notimpl }, | ||
72 | MU_OPTION_END | ||
73 | }; | ||
134 | 74 | ||
135 | default: | 75 | static int list_message (size_t num, mu_message_t msg, void *data); |
136 | return ARGP_ERR_UNKNOWN; | 76 | void print_header (mu_mailbox_t mbox); |
137 | } | 77 | void clear_screen (void); |
138 | return 0; | ||
139 | } | ||
140 | 78 | ||
141 | /* Observable Action this is called at every message discover. */ | 79 | /* Observable Action this is called at every message discover. */ |
142 | static int | 80 | static int |
... | @@ -161,7 +99,6 @@ action (mu_observer_t o, size_t type, void *data, void *action_data) | ... | @@ -161,7 +99,6 @@ action (mu_observer_t o, size_t type, void *data, void *action_data) |
161 | int | 99 | int |
162 | main (int argc, char **argv) | 100 | main (int argc, char **argv) |
163 | { | 101 | { |
164 | int index; | ||
165 | mu_mailbox_t mbox; | 102 | mu_mailbox_t mbox; |
166 | int status; | 103 | int status; |
167 | size_t total = 0; | 104 | size_t total = 0; |
... | @@ -169,9 +106,8 @@ main (int argc, char **argv) | ... | @@ -169,9 +106,8 @@ main (int argc, char **argv) |
169 | /* Native Language Support */ | 106 | /* Native Language Support */ |
170 | MU_APP_INIT_NLS (); | 107 | MU_APP_INIT_NLS (); |
171 | 108 | ||
172 | mh_argp_init (); | 109 | mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, |
173 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 110 | args_doc, progdoc, NULL); |
174 | opt_handler, NULL, &index); | ||
175 | 111 | ||
176 | if (mh_format_parse (format_str, &format)) | 112 | if (mh_format_parse (format_str, &format)) |
177 | { | 113 | { |
... | @@ -181,8 +117,6 @@ main (int argc, char **argv) | ... | @@ -181,8 +117,6 @@ main (int argc, char **argv) |
181 | 117 | ||
182 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); | 118 | mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); |
183 | 119 | ||
184 | argc -= index; | ||
185 | argv += index; | ||
186 | if ((argc == 0 || strcmp (argv[0], "all") == 0) && !reverse) | 120 | if ((argc == 0 || strcmp (argv[0], "all") == 0) && !reverse) |
187 | { | 121 | { |
188 | /* Fast approach */ | 122 | /* Fast approach */ | ... | ... |
... | @@ -90,7 +90,7 @@ Regards, | ... | @@ -90,7 +90,7 @@ Regards, |
90 | Sergey | 90 | Sergey |
91 | ]) | 91 | ]) |
92 | 92 | ||
93 | burst +inbox --length=7 1 || exit $? | 93 | burst +inbox -length 7 1 || exit $? |
94 | grep -v ^X-Envelope- Mail/inbox/2 | 94 | grep -v ^X-Envelope- Mail/inbox/2 |
95 | grep -v ^X-Envelope- Mail/inbox/3 | 95 | grep -v ^X-Envelope- Mail/inbox/3 |
96 | grep -v ^X-Envelope- Mail/inbox/4 | 96 | grep -v ^X-Envelope- Mail/inbox/4 |
... | @@ -140,7 +140,7 @@ With gently smiling jaws! | ... | @@ -140,7 +140,7 @@ With gently smiling jaws! |
140 | 140 | ||
141 | MH_CHECK([burst mime recursive],[burst03 burst-mime-recursive],[ | 141 | MH_CHECK([burst mime recursive],[burst03 burst-mime-recursive],[ |
142 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | 142 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) |
143 | burst +inbox --recursive 4 || exit $? | 143 | burst +inbox -recursive 4 || exit $? |
144 | grep -v ^X-Envelope- Mail/inbox/6 | 144 | grep -v ^X-Envelope- Mail/inbox/6 |
145 | grep -v ^X-Envelope- Mail/inbox/7 | 145 | grep -v ^X-Envelope- Mail/inbox/7 |
146 | grep -v ^X-Envelope- Mail/inbox/8 | 146 | grep -v ^X-Envelope- Mail/inbox/8 | ... | ... |
... | @@ -99,13 +99,13 @@ Mail/inbox/4 | ... | @@ -99,13 +99,13 @@ Mail/inbox/4 |
99 | Mail/inbox/5 | 99 | Mail/inbox/5 |
100 | ]) | 100 | ]) |
101 | 101 | ||
102 | MH_CHECK([folder --pack=N],[folder06 folder--pack=N],[ | 102 | MH_CHECK([folder -pack=N],[folder06 folder-pack=N],[ |
103 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | 103 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) |
104 | for i in 1 2 3 4 5 | 104 | for i in 1 2 3 4 5 |
105 | do | 105 | do |
106 | mv Mail/inbox/$i Mail/inbox/${i}0 | 106 | mv Mail/inbox/$i Mail/inbox/${i}0 |
107 | done | 107 | done |
108 | folder --pack=1 || exit $? | 108 | folder -pack=1 || exit $? |
109 | find Mail/inbox -not -name '.mu-prop' | sort | 109 | find Mail/inbox -not -name '.mu-prop' | sort |
110 | ], | 110 | ], |
111 | [0], | 111 | [0], | ... | ... |
-
Please register or sign in to post a comment