Commit e267ac86 e267ac86e2c3a78979fe12bdd16392f30f8d1725 by Sergey Poznyakoff

Finish conversion of MH utilities to mh_parseopt

This finishes work started at commit bc73fc65.

* include/mailutils/opt.h (mu_option_cache) <cache_arg>: Made const.
* libmailutils/opt/opt.c (mu_option_cache_destroy): Don't free cache_arg.
* doc/texinfo/mu-mh.texi: Update.

* po/POTFILES.in: Remove obsolete files.
* mh/tests/refile.at: Don't use double-dash options.

* mh/mh_getopt.c (mh_opt_set_folder): New function.
* mh/mh_getopt.h: Likewise.

* mh/mhn.c: Convert to mh_getopt.
* mh/mhparam.c: Likewise.
* mh/mhpath.c: Likewise.
* mh/mhseq.c: Likewise.
* mh/msgchk.c: Likewise.
* mh/pick.c: Likewise.
* mh/pick.h: Likewise.
* mh/pick.y: Likewise.
* mh/prompter.c: Likewise.
* mh/refile.c: Likewise.
* mh/repl.c: Likewise.
* mh/rmf.c: Likewise.
* mh/rmm.c: Likewise.
* mh/scan.c: Likewise.
* mh/send.c: Likewise.
* mh/show.c: Likewise.
* mh/sortm.c: Likewise.
* mh/whatnow.c: Likewise.
* mh/whom.c: Likewise.
1 parent f434857b
...@@ -27,9 +27,6 @@ distribution directory. ...@@ -27,9 +27,6 @@ distribution directory.
27 @subsection Major differences between Mailutils MH and other MH implementations 27 @subsection Major differences between Mailutils MH and other MH implementations
28 28
29 @enumerate 1 29 @enumerate 1
30 @item All programs use usual GNU long options. The support for MH single-dash
31 options is provided for backward compatibility;
32
33 @item UUCP addresses are not supported; 30 @item UUCP addresses are not supported;
34 31
35 @item Mailutils supports a set of new format specifications 32 @item Mailutils supports a set of new format specifications
...@@ -38,6 +35,12 @@ options is provided for backward compatibility; ...@@ -38,6 +35,12 @@ options is provided for backward compatibility;
38 @item Mailutils provides a set of new profile variables 35 @item Mailutils provides a set of new profile variables
39 (@pxref{Profile Variable Diffs}); 36 (@pxref{Profile Variable Diffs});
40 37
38 @item All programs recognize @option{--help} and @option{--version} options
39
40 These options are recognized only if no other arguments are present in
41 the command line. Abbreviations are not recognized. This makes Mailutils
42 MH implementation compatible with the standard usage for GNU tools.
43
41 @item Several programs behave differently (@pxref{Program 44 @item Several programs behave differently (@pxref{Program
42 Diffs}); 45 Diffs});
43 46
...@@ -150,7 +153,7 @@ This expression is used in default @file{replcomps} and ...@@ -150,7 +153,7 @@ This expression is used in default @file{replcomps} and
150 @deftypefn {MH Format} boolean rcpt (@samp{to} | @samp{cc} | @samp{me} | @samp{all}) 153 @deftypefn {MH Format} boolean rcpt (@samp{to} | @samp{cc} | @samp{me} | @samp{all})
151 154
152 This function returns true if the given element is present in the 155 This function returns true if the given element is present in the
153 recipient mask (as modified by @option{--cc} or @option{--nocc} options) and 156 recipient mask (as modified by @option{-cc} or @option{-nocc} options) and
154 false otherwise. It is used in default formats for @command{repl} and 157 false otherwise. It is used in default formats for @command{repl} and
155 @command{comp}, e.g.: 158 @command{comp}, e.g.:
156 159
...@@ -159,7 +162,7 @@ false otherwise. It is used in default formats for @command{repl} and ...@@ -159,7 +162,7 @@ false otherwise. It is used in default formats for @command{repl} and
159 @end smallexample 162 @end smallexample
160 163
161 Notice that this means that usual @file{replcomps} file will be ignoring 164 Notice that this means that usual @file{replcomps} file will be ignoring
162 @option{--cc} and @option{--nocc} options, unless it has been modified 165 @option{-cc} and @option{-nocc} options, unless it has been modified
163 as shown above. 166 as shown above.
164 @end deftypefn 167 @end deftypefn
165 168
...@@ -226,12 +229,12 @@ RAND @command{anno} displays the prompt anyway. ...@@ -226,12 +229,12 @@ RAND @command{anno} displays the prompt anyway.
226 229
227 The utility is able to burst both RFC 934 digest messages and MIME 230 The utility is able to burst both RFC 934 digest messages and MIME
228 multipart messages. It provides two additional command line options: 231 multipart messages. It provides two additional command line options:
229 @option{--recurse} and @option{--length}. 232 @option{-recurse} and @option{-length}.
230 233
231 The @option{--recurse} option instructs the utility to recursively 234 The @option{-recurse} option instructs the utility to recursively
232 expand the digest. 235 expand the digest.
233 236
234 The @option{--length} option can be used to set the minimal encapsulation 237 The @option{-length} option can be used to set the minimal encapsulation
235 boundary length for RFC 934 digests. Default length is 1, 238 boundary length for RFC 934 digests. Default length is 1,
236 i.e. encountering one dash immediately following a newline triggers 239 i.e. encountering one dash immediately following a newline triggers
237 digest decoding. It is OK for messages that follow RFC 934 240 digest decoding. It is OK for messages that follow RFC 934
...@@ -239,12 +242,12 @@ specification. However, many user agents do not precisely follow it, ...@@ -239,12 +242,12 @@ specification. However, many user agents do not precisely follow it,
239 in particular, they often do not escape lines starting with a dash by 242 in particular, they often do not escape lines starting with a dash by
240 @samp{- } sequence. @command{Mailman} is one of such agents. To cope 243 @samp{- } sequence. @command{Mailman} is one of such agents. To cope
241 with such digests you can set encapsulation boundary length to a higher 244 with such digests you can set encapsulation boundary length to a higher
242 value. For example, @command{bounce --length=8} has been found to be 245 value. For example, @command{bounce -length 8} has been found to be
243 sufficient for most Mailman-generated digests. 246 sufficient for most Mailman-generated digests.
244 247
245 @item comp 248 @item comp
246 249
247 Understands @option{--build} option. 250 Understands @option{-build} option.
248 251
249 @item fmtdump 252 @item fmtdump
250 253
...@@ -252,24 +255,24 @@ This command is not provided. Use @option{fmtcheck} instead. ...@@ -252,24 +255,24 @@ This command is not provided. Use @option{fmtcheck} instead.
252 255
253 @item inc 256 @item inc
254 @itemize @bullet 257 @itemize @bullet
255 @item The @option{--moveto} option. 258 @item The @option{-moveto} option.
256 The @option{--moveto} option instructs @command{inc} to move 259 The @option{-moveto} option instructs @command{inc} to move
257 messages into another folder after incorporating them. This option 260 messages into another folder after incorporating them. This option
258 has effect only if the @option{--truncate} option has also been 261 has effect only if the @option{-truncate} option has also been
259 specified and the underlying mailbox supports the @samp{move} 262 specified and the underlying mailbox supports the @samp{move}
260 operation. Currently only @samp{imap} and @samp{imaps} mailboxes 263 operation. Currently only @samp{imap} and @samp{imaps} mailboxes
261 support it. For example, the following command moves incorporated 264 support it. For example, the following command moves incorporated
262 messages into the @samp{archive} folder: 265 messages into the @samp{archive} folder:
263 266
264 @example 267 @example
265 inc --file imaps://imap.gmail.com --moveto=archive 268 inc -file imaps://imap.gmail.com -moveto=archive
266 @end example 269 @end example
267 270
268 The @samp{moveto} URL parameter can be used instead of this option, 271 The @samp{moveto} URL parameter can be used instead of this option,
269 e.g.: 272 e.g.:
270 273
271 @example 274 @example
272 inc --file 'imaps://imap.gmail.com;moveto=archive' 275 inc -file 'imaps://imap.gmail.com;moveto=archive'
273 @end example 276 @end example
274 277
275 @item Multiple sources 278 @item Multiple sources
...@@ -294,7 +297,7 @@ Moves incorporated messages into another folder. This was discussed ...@@ -294,7 +297,7 @@ Moves incorporated messages into another folder. This was discussed
294 above. 297 above.
295 298
296 @item nomoveto 299 @item nomoveto
297 Disables the previous @option{--moveto} option. 300 Disables the previous @option{-moveto} option.
298 301
299 @item truncate[=@var{bool}] 302 @item truncate[=@var{bool}]
300 Controls source mailbox truncation. If @var{bool} is not given or it is 303 Controls source mailbox truncation. If @var{bool} is not given or it is
...@@ -333,13 +336,13 @@ The following format variables are silently ignored: @samp{center}, ...@@ -333,13 +336,13 @@ The following format variables are silently ignored: @samp{center},
333 @itemize @bullet 336 @itemize @bullet
334 337
335 @item New option 338 @item New option
336 New option @option{--compose} forces @command{mhn} editing mode. This 339 New option @option{-compose} forces @command{mhn} editing mode. This
337 is also the default mode. This differs from the standard 340 is also the default mode. This differs from the standard
338 @command{mhn}, which switches to the editing mode only if no other 341 @command{mhn}, which switches to the editing mode only if no other
339 options were given and the input file name coincides with the value of 342 options were given and the input file name coincides with the value of
340 @env{mhdraft} environment variable. 343 @env{mhdraft} environment variable.
341 344
342 @item Show mode (@option{--show}) 345 @item Show mode (@option{-show})
343 If an appropriate mhn-show-type[/subtype] was not found, GNU @command{mhn} 346 If an appropriate mhn-show-type[/subtype] was not found, GNU @command{mhn}
344 prints the decoded message content using @code{moreproc} 347 prints the decoded message content using @code{moreproc}
345 variable. Standard @command{mhn} in this case used to print @samp{don't 348 variable. Standard @command{mhn} in this case used to print @samp{don't
...@@ -349,47 +352,28 @@ The default behaviour is to pipe the content to the standard input ...@@ -349,47 +352,28 @@ The default behaviour is to pipe the content to the standard input
349 of the mhn-show-type[/subtype] command. This is altered to using a 352 of the mhn-show-type[/subtype] command. This is altered to using a
350 temporary file if the command contains @code{%f} or @code{%F} escapes. 353 temporary file if the command contains @code{%f} or @code{%F} escapes.
351 354
352 @item Store mode (@option{--store}) 355 @item Store mode (@option{-store})
353 If the @code{Content-Disposition} header contains @samp{filename=}, 356 If the @code{Content-Disposition} header contains @samp{filename=},
354 and @command{mhn} is invoked with @option{--auto} switch, it 357 and @command{mhn} is invoked with @option{-auto} switch, it
355 transforms the file name into the absolute notation and uses it only 358 transforms the file name into the absolute notation and uses it only
356 if it lies below the current mhn-storage directory. Standard 359 if it lies below the current mhn-storage directory. Standard
357 @command{mhn} only requires that the file name do not begin with @samp{/}. 360 @command{mhn} only requires that the file name do not begin with @samp{/}.
358 361
359 Before saving a message part, GNU @command{mhn} checks if the file already 362 Before saving a message part, GNU @command{mhn} checks if the file already
360 exists. If so, it asks whether the user wishes to rewrite it. This 363 exists. If so, it asks whether the user wishes to rewrite it. This
361 behaviour is disabled when @option{--quiet} option was given. 364 behaviour is disabled when @option{-quiet} option was given.
362 @end itemize 365 @end itemize
363 366
364 @item mhparam 367 @item mhparam
365 368
366 The @option{--all} mode does not display commented out entries. 369 The @option{-all} mode does not display commented out entries.
367 370
368 @item pick 371 @item pick
369 372
370 The command line syntax @option{--@var{component} @var{string}}) is 373 New command line option @option{-cflags} allows to control the type of
371 recognized only if at least one of the following conditions is met:
372
373 @itemize @bullet
374 @item The word @var{component} contains at least one capital letter.
375 E.g. @option{--User-Agent Mailutils}.
376
377 @item The word @var{component} ends with a colon, as in
378 @option{user-agent: Mailutils}.
379
380 @item Standard input is not connected to a terminal.
381 @end itemize
382
383 The GNU syntax for component matching is:
384
385 @smallexample
386 pick --component @var{field} --pattern @var{string}
387 @end smallexample
388
389 New command line option @option{--cflags} allows to control the type of
390 regular expressions used. The option must occur right before 374 regular expressions used. The option must occur right before
391 @option{--pattern} or @option{--component} option (or one of its 375 @option{--@var{component} @var{pattern}} or equivalent construct (like
392 aliases, like @option{--cc}, @option{--from}, etc.) 376 @option{-cc}, @option{-from}, etc.)
393 377
394 The argument to this option is a string of type specifications: 378 The argument to this option is a string of type specifications:
395 379
...@@ -402,24 +386,24 @@ The argument to this option is a string of type specifications: ...@@ -402,24 +386,24 @@ The argument to this option is a string of type specifications:
402 386
403 Default is @samp{EI}. 387 Default is @samp{EI}.
404 388
405 The flags remain in effect until the next occurrence of @option{--cflags} 389 The flags remain in effect until the next occurrence of @option{-cflags}
406 option. 390 option.
407 391
408 Sample usage: 392 Sample usage:
409 393
410 @smallexample 394 @smallexample
411 pick --cflag BC --subject '*a string' 395 pick -cflag BC -subject '*a string'
412 @end smallexample 396 @end smallexample
413 397
414 The date comparison options (@option{--before} and @option{--after} 398 The date comparison options (@option{-before} and @option{-after}
415 accept date specifications in a wide variety of formats, e.g.: 399 accept date specifications in a wide variety of formats, e.g.:
416 400
417 @smallexample 401 @smallexample
418 pick --after 20030301 402 pick -after 20030301
419 pick --after 2003-03-01 403 pick -after 2003-03-01
420 pick --after 01-mar-2003 404 pick -after 01-mar-2003
421 pick --after 2003-mar-01 405 pick -after 2003-mar-01
422 pick --before '1 year ago' 406 pick -before '1 year ago'
423 etc... 407 etc...
424 @end smallexample 408 @end smallexample
425 409
...@@ -454,11 +438,11 @@ will add it automatically. ...@@ -454,11 +438,11 @@ will add it automatically.
454 @item 438 @item
455 Linking messages between folders goes against the logic of Mailutils, 439 Linking messages between folders goes against the logic of Mailutils,
456 so @command{refile} never makes links even if called with 440 so @command{refile} never makes links even if called with
457 @option{--link} option. The latter is actually a synonym for @option{--copy}, 441 @option{-link} option. The latter is actually a synonym for @option{-copy},
458 which preserves the original message. 442 which preserves the original message.
459 443
460 @item 444 @item
461 The @option{--preserve} option is not implemented. It is retained for backward 445 The @option{-preserve} option is not implemented. It is retained for backward
462 compatibility only. 446 compatibility only.
463 447
464 @item 448 @item
...@@ -467,7 +451,7 @@ Message specs and folder names may be interspersed. ...@@ -467,7 +451,7 @@ Message specs and folder names may be interspersed.
467 451
468 @item repl 452 @item repl
469 453
470 Understands @option{--use} option. Disposition shell provides 454 Understands @option{-use} option. Disposition shell provides
471 @code{use} command. 455 @code{use} command.
472 456
473 @item rmm 457 @item rmm
...@@ -491,14 +475,14 @@ rmmproc: ...@@ -491,14 +475,14 @@ rmmproc:
491 475
492 @item sortm 476 @item sortm
493 477
494 New option @option{--numfield} specifies numeric comparison for the 478 New option @option{-numfield} specifies numeric comparison for the
495 given field. 479 given field.
496 480
497 Any number of @option{--datefield}, @option{--textfield} and 481 Any number of @option{-datefield}, @option{-textfield} and
498 @option{--numfield} options may be given, thus allowing to build sort 482 @option{-numfield} options may be given, thus allowing to build sort
499 criteria of arbitrary complexity. 483 criteria of arbitrary complexity.
500 484
501 The order of @option{--.*field} options sets the ordering priority. This 485 The order of @option{-.*field} options sets the ordering priority. This
502 differs from the behaviour of the standard @command{sortm}, which 486 differs from the behaviour of the standard @command{sortm}, which
503 always orders datefield-major, textfield-minor. 487 always orders datefield-major, textfield-minor.
504 488
...@@ -506,11 +490,11 @@ Apart from sorting the mailfolder the following actions may be ...@@ -506,11 +490,11 @@ Apart from sorting the mailfolder the following actions may be
506 specified: 490 specified:
507 491
508 @table @option 492 @table @option
509 @item --list 493 @item -list
510 List the ordered messages using a format string given by 494 List the ordered messages using a format string given by
511 @option{--form} or @option{--format} option. 495 @option{-form} or @option{-format} option.
512 496
513 @item --dry-run 497 @item -dry-run
514 Do not actually sort messages, rather print what would have been 498 Do not actually sort messages, rather print what would have been
515 done. This is useful for debugging purposes. 499 done. This is useful for debugging purposes.
516 @end table 500 @end table
......
...@@ -71,7 +71,7 @@ typedef struct mu_option_cache *mu_option_cache_ptr_t; ...@@ -71,7 +71,7 @@ typedef struct mu_option_cache *mu_option_cache_ptr_t;
71 struct mu_option_cache 71 struct mu_option_cache
72 { 72 {
73 struct mu_option *cache_opt; 73 struct mu_option *cache_opt;
74 char *cache_arg; 74 char const *cache_arg;
75 }; 75 };
76 76
77 #define MU_PARSEOPT_DEFAULT 0 77 #define MU_PARSEOPT_DEFAULT 0
......
...@@ -136,7 +136,6 @@ static void ...@@ -136,7 +136,6 @@ static void
136 mu_option_cache_destroy (void *ptr) 136 mu_option_cache_destroy (void *ptr)
137 { 137 {
138 struct mu_option_cache *cache = ptr; 138 struct mu_option_cache *cache = ptr;
139 free (cache->cache_arg);
140 free (cache); 139 free (cache);
141 } 140 }
142 141
...@@ -150,7 +149,7 @@ add_option_cache (struct mu_parseopt *po, struct mu_option *opt, ...@@ -150,7 +149,7 @@ add_option_cache (struct mu_parseopt *po, struct mu_option *opt,
150 { 149 {
151 struct mu_option_cache *cache = mu_alloc (sizeof (*cache)); 150 struct mu_option_cache *cache = mu_alloc (sizeof (*cache));
152 cache->cache_opt = opt; 151 cache->cache_opt = opt;
153 cache->cache_arg = arg ? mu_strdup (arg) : NULL; 152 cache->cache_arg = arg;
154 153
155 if ((po->po_flags & MU_PARSEOPT_IMMEDIATE) 154 if ((po->po_flags & MU_PARSEOPT_IMMEDIATE)
156 || (opt->opt_flags & MU_OPTION_IMMEDIATE)) 155 || (opt->opt_flags & MU_OPTION_IMMEDIATE))
...@@ -774,7 +773,7 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, ...@@ -774,7 +773,7 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt,
774 free (errmsg); 773 free (errmsg);
775 774
776 if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT)) 775 if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT))
777 exit (EXIT_ERROR); 776 exit (po->po_exit_error);
778 } 777 }
779 } 778 }
780 } 779 }
......
...@@ -79,6 +79,23 @@ augment_argv (int *pargc, char ***pargv) ...@@ -79,6 +79,23 @@ augment_argv (int *pargc, char ***pargv)
79 } 79 }
80 80
81 static void 81 static void
82 process_std_options (int argc, char **argv, struct mu_parseopt *po)
83 {
84 if (argc != 1)
85 return;
86 if (strcmp (argv[0], "--help") == 0)
87 {
88 mu_program_help (po, mu_strout);
89 exit (0);
90 }
91 if (strcmp (argv[0], "--version") == 0)
92 {
93 mu_program_version (po, mu_strout);
94 exit (0);
95 }
96 }
97
98 static void
82 process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po) 99 process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po)
83 { 100 {
84 int i, j; 101 int i, j;
...@@ -109,8 +126,9 @@ process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po) ...@@ -109,8 +126,9 @@ process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po)
109 *pargc = j; 126 *pargc = j;
110 } 127 }
111 128
112 static void 129 void
113 set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg) 130 mh_opt_set_folder (struct mu_parseopt *po, struct mu_option *opt,
131 char const *arg)
114 { 132 {
115 mh_set_current_folder (arg); 133 mh_set_current_folder (arg);
116 } 134 }
...@@ -118,7 +136,45 @@ set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg) ...@@ -118,7 +136,45 @@ set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
118 static struct mu_option folder_option[] = { 136 static struct mu_option folder_option[] = {
119 { "folder", 0, NULL, MU_OPTION_DEFAULT, 137 { "folder", 0, NULL, MU_OPTION_DEFAULT,
120 N_("set current folder"), 138 N_("set current folder"),
121 mu_c_string, NULL, set_folder }, 139 mu_c_string, NULL, mh_opt_set_folder },
140 MU_OPTION_END
141 };
142
143 void
144 mh_version_hook (struct mu_parseopt *po, mu_stream_t stream)
145 {
146 extern const char mu_version_copyright[];
147 #ifdef GIT_DESCRIBE
148 mu_stream_printf (stream, "%s (GNU MH, %s) %s [%s]\n",
149 mu_program_name, PACKAGE_NAME, PACKAGE_VERSION,
150 GIT_DESCRIBE);
151 #else
152 mu_stream_printf (stream, "%s (GNU MH, %s) %s\n", mu_program_name,
153 PACKAGE_NAME, PACKAGE_VERSION);
154 #endif
155 /* TRANSLATORS: Translate "(C)" to the copyright symbol
156 (C-in-a-circle), if this symbol is available in the user's
157 locale. Otherwise, do not translate "(C)"; leave it as-is. */
158 mu_stream_printf (stream, mu_version_copyright, _("(C)"));
159 mu_stream_printf (stream, _("\
160 \n\
161 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\
162 There is NO WARRANTY, to the extent permitted by law.\n\
163 \n\
164 "));
165 }
166
167 static void
168 fn_version (struct mu_parseopt *po, struct mu_option *opt, char const *unused)
169 {
170 mu_program_version (po, mu_strout);
171 exit (0);
172 }
173
174 static struct mu_option version_option[] = {
175 { "version", 0, NULL, MU_OPTION_DEFAULT,
176 N_("print program version"),
177 mu_c_string, NULL, fn_version },
122 MU_OPTION_END 178 MU_OPTION_END
123 }; 179 };
124 180
...@@ -132,7 +188,7 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, ...@@ -132,7 +188,7 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
132 struct mu_parseopt po; 188 struct mu_parseopt po;
133 struct mu_option *optv[3]; 189 struct mu_option *optv[3];
134 struct getopt_data getopt_data; 190 struct getopt_data getopt_data;
135 char const *args[2]; 191 char const *args[3];
136 int flags = MU_PARSEOPT_SINGLE_DASH | MU_PARSEOPT_IMMEDIATE; 192 int flags = MU_PARSEOPT_SINGLE_DASH | MU_PARSEOPT_IMMEDIATE;
137 int i; 193 int i;
138 194
...@@ -177,6 +233,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, ...@@ -177,6 +233,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
177 //po.po_extra_info = gnu_general_help_url; 233 //po.po_extra_info = gnu_general_help_url;
178 //flags |= MU_PARSEOPT_EXTRA_INFO; 234 //flags |= MU_PARSEOPT_EXTRA_INFO;
179 235
236 po.po_version_hook = mh_version_hook;
237 flags |= MU_PARSEOPT_VERSION_HOOK;
238
180 mu_set_program_name (argv[0]); 239 mu_set_program_name (argv[0]);
181 mh_init (); 240 mh_init ();
182 augment_argv (&argc, &argv); 241 augment_argv (&argc, &argv);
...@@ -184,7 +243,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, ...@@ -184,7 +243,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
184 i = 0; 243 i = 0;
185 if (mhflags & MH_GETOPT_DEFAULT_FOLDER) 244 if (mhflags & MH_GETOPT_DEFAULT_FOLDER)
186 optv[i++] = folder_option; 245 optv[i++] = folder_option;
246 if (options)
187 optv[i++] = options; 247 optv[i++] = options;
248 optv[i++] = version_option;
188 optv[i] = NULL; 249 optv[i] = NULL;
189 250
190 if (mu_parseopt (&po, argc, argv, optv, flags)) 251 if (mu_parseopt (&po, argc, argv, optv, flags))
...@@ -193,6 +254,8 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options, ...@@ -193,6 +254,8 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
193 argc -= po.po_arg_start; 254 argc -= po.po_arg_start;
194 argv += po.po_arg_start; 255 argv += po.po_arg_start;
195 256
257 process_std_options (argc, argv, &po);
258
196 process_folder_arg (&argc, argv, &po); 259 process_folder_arg (&argc, argv, &po);
197 260
198 if (!argdoc && argc) 261 if (!argdoc && argc)
......
...@@ -35,5 +35,7 @@ void mh_opt_find_file (struct mu_parseopt *po, struct mu_option *opt, ...@@ -35,5 +35,7 @@ void mh_opt_find_file (struct mu_parseopt *po, struct mu_option *opt,
35 char const *arg); 35 char const *arg);
36 void mh_opt_read_formfile (struct mu_parseopt *po, struct mu_option *opt, 36 void mh_opt_read_formfile (struct mu_parseopt *po, struct mu_option *opt,
37 char const *arg); 37 char const *arg);
38 void mh_opt_set_folder (struct mu_parseopt *po, struct mu_option *opt,
39 char const *arg);
38 40
39 41
......
...@@ -22,99 +22,9 @@ ...@@ -22,99 +22,9 @@
22 #include <mailutils/mime.h> 22 #include <mailutils/mime.h>
23 #include <setjmp.h> 23 #include <setjmp.h>
24 24
25 static char doc[] = N_("GNU MH mhn")"\v" 25 static char prog_doc[] = N_("GNU MH mhn");
26 N_("Options marked with `*' are not yet implemented.\n\
27 Use -help to obtain the list of traditional MH options.");
28 static char args_doc[] = N_("[MSGLIST]"); 26 static char args_doc[] = N_("[MSGLIST]");
29 27
30 static struct argp_option options[] = {
31 {"folder", ARG_FOLDER, N_("FOLDER"), 0,
32 N_("specify folder to operate upon"), 0},
33 {"file", ARG_FILE, N_("FILE"), 0,
34 N_("specify file to operate upon"), 0},
35
36 #define GRID 10
37 {N_("MIME editing options"), 0, NULL, OPTION_DOC, NULL, GRID},
38 {"compose", ARG_COMPOSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
39 N_("compose the MIME message (default)"), GRID+1},
40 {"build", 0, NULL, OPTION_ALIAS,
41 NULL, GRID+1 },
42 {"nocompose", ARG_NOCOMPOSE, NULL, OPTION_HIDDEN, NULL, GRID+1},
43 {"nobuild", ARG_NOCOMPOSE, NULL, OPTION_HIDDEN|OPTION_ALIAS,
44 NULL, GRID+1},
45 #undef GRID
46 #define GRID 20
47 {N_("Listing options"), 0, NULL, OPTION_DOC, NULL, GRID},
48 {"list", ARG_LIST, N_("BOOL"), OPTION_ARG_OPTIONAL,
49 N_("list the table of contents"), GRID+1 },
50 {"nolist", ARG_NOLIST, NULL, OPTION_HIDDEN, "", GRID+1 },
51 {"headers", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL,
52 N_("print the banner above the listing"), GRID+1 },
53 {"noheaders", ARG_NOHEADERS, NULL, OPTION_HIDDEN, "", GRID+1 },
54 {"realsize", ARG_REALSIZE, N_("BOOL"), OPTION_ARG_OPTIONAL,
55 N_("list the decoded sizes"), GRID+1 },
56 {"norealsize", ARG_NOREALSIZE, NULL, OPTION_HIDDEN, "", GRID+1 },
57 #undef GRID
58 #define GRID 40
59 {N_("Display options"), 0, NULL, OPTION_DOC, NULL, GRID},
60 {"show", ARG_SHOW, N_("BOOL"), OPTION_ARG_OPTIONAL,
61 N_("display the contents of the messages"), GRID+1},
62 {"noshow", ARG_NOSHOW, NULL, OPTION_HIDDEN, "", GRID+1 },
63 {"serialonly", ARG_SERIALONLY, N_("BOOL"), OPTION_ARG_OPTIONAL,
64 N_("* display messages serially"), GRID+1},
65 {"noserialonly", ARG_NOSERIALONLY, NULL, OPTION_HIDDEN, "", GRID+1 },
66 {"form", ARG_FORM, N_("FILE"), 0,
67 N_("read mhl format from FILE"), GRID+1},
68 {"pause", ARG_PAUSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
69 N_("pause prior to displaying content"), GRID+1},
70 {"nopause", ARG_NOPAUSE, NULL, OPTION_HIDDEN, "", GRID+1 },
71 #undef GRID
72 #define GRID 50
73 {N_("Saving options"), 0, NULL, OPTION_DOC, NULL, GRID},
74 {"store", ARG_STORE, N_("BOOL"), OPTION_ARG_OPTIONAL,
75 N_("write extracted message parts to disk"), GRID+1},
76 {"nostore", ARG_NOSTORE, NULL, OPTION_HIDDEN, "", GRID+1 },
77 {"auto", ARG_AUTO, N_("BOOL"), OPTION_ARG_OPTIONAL,
78 N_("use filenames from the content headers"), GRID+1},
79 {"noauto", ARG_NOAUTO, NULL, OPTION_HIDDEN, "", GRID+1 },
80 {"charset", ARG_CHARSET, N_("NAME"), 0,
81 N_("use this charset to represent attachment file names"), GRID+1},
82 #undef GRID
83 #define GRID 60
84 {N_("Other options"), 0, NULL, OPTION_DOC, NULL, GRID},
85 {"part", ARG_PART, N_("PART"), 0,
86 N_("limit the scope of the operation to the given part"), GRID+1},
87 {"type", ARG_TYPE, N_("CONTENT"), 0,
88 N_("operate on message part with given multipart content"), GRID+1 },
89 {"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
90 N_("print additional information"), GRID+1 },
91 {"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "", GRID+1 },
92 {"quiet", ARG_QUIET, 0, 0,
93 N_("be quiet"), GRID+1},
94 #undef GRID
95 {NULL}
96 };
97
98 /* Traditional MH options */
99 struct mh_option mh_option[] = {
100 { "file", MH_OPT_ARG, "filename" },
101 { "compose" },
102 { "build" },
103 { "list", MH_OPT_BOOL },
104 { "headers", MH_OPT_BOOL },
105 { "realsize", MH_OPT_BOOL },
106 { "show", MH_OPT_BOOL },
107 { "serialonly", MH_OPT_BOOL },
108 { "form", MH_OPT_ARG, "formfile" },
109 { "pause", MH_OPT_BOOL },
110 { "store", MH_OPT_BOOL },
111 { "auto", MH_OPT_BOOL },
112 { "part", MH_OPT_ARG, "part" },
113 { "type", MH_OPT_ARG, "type" },
114 { "verbose", MH_OPT_BOOL },
115 { NULL }
116 };
117
118 typedef struct _msg_part *msg_part_t; 28 typedef struct _msg_part *msg_part_t;
119 29
120 static msg_part_t msg_part_create (size_t num); 30 static msg_part_t msg_part_create (size_t num);
...@@ -124,28 +34,22 @@ static void msg_part_incr (msg_part_t p); ...@@ -124,28 +34,22 @@ static void msg_part_incr (msg_part_t p);
124 static void msg_part_decr (msg_part_t p); 34 static void msg_part_decr (msg_part_t p);
125 static void msg_part_set_subpart (msg_part_t p, size_t subpart); 35 static void msg_part_set_subpart (msg_part_t p, size_t subpart);
126 static void msg_part_print (msg_part_t p, int width); 36 static void msg_part_print (msg_part_t p, int width);
127 static msg_part_t msg_part_parse (char *str); 37 static msg_part_t msg_part_parse (char const *str);
128 static int msg_part_level (msg_part_t p); 38 static int msg_part_level (msg_part_t p);
129 static size_t msg_part_subpart (msg_part_t p, int level); 39 static size_t msg_part_subpart (msg_part_t p, int level);
130 40
131 enum mhn_mode 41 static int compose_option;
132 { 42 static int list_option;
133 mode_compose, 43 static int show_option;
134 mode_list, 44 static int store_option;
135 mode_show,
136 mode_store,
137 };
138 45
139 static enum mhn_mode mode = mode_compose; 46 static int headers_option = 1;
47 static int realsize_option;
48 static int auto_option;
49 /*static int serialonly_option;*/
50 static int verbose_option;
51 static int quiet_option;
140 52
141 #define OPT_HEADERS 001
142 #define OPT_REALSIZE 002
143 #define OPT_AUTO 004
144 #define OPT_SERIALONLY 010
145 #define OPT_VERBOSE 020
146 #define OPT_QUIET 040
147
148 static int mode_options = OPT_HEADERS;
149 static int pause_option = -1; /* -pause option. -1 means "not given" */ 53 static int pause_option = -1; /* -pause option. -1 means "not given" */
150 static char *formfile; 54 static char *formfile;
151 static char *content_type; 55 static char *content_type;
...@@ -261,172 +165,87 @@ _get_content_encoding (mu_header_t hdr, char **value) ...@@ -261,172 +165,87 @@ _get_content_encoding (mu_header_t hdr, char **value)
261 return 0; 165 return 0;
262 } 166 }
263 167
264 static error_t 168 static void
265 opt_handler (int key, char *arg, struct argp_state *state) 169 set_part (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
266 { 170 {
267 switch (key) 171 req_part = msg_part_parse (arg);
268 { 172 }
269 case ARG_FOLDER:
270 mh_set_current_folder (arg);
271 break;
272
273 case ARG_FILE:
274 input_file = arg;
275 break;
276
277 /* Operation mode */
278 case ARG_COMPOSE:
279 if (is_true (arg))
280 {
281 mode = mode_compose;
282 break;
283 }
284 /*FALLTHRU*/
285 case ARG_NOCOMPOSE:
286 if (mode == mode_compose)
287 mode = mode_compose;
288 break;
289
290 case ARG_LIST:
291 if (is_true (arg))
292 {
293 mode = mode_list;
294 break;
295 }
296 /*FALLTHRU*/
297 case ARG_NOLIST:
298 if (mode == mode_list)
299 mode = mode_compose;
300 break;
301
302 case ARG_SHOW:
303 if (is_true (arg))
304 {
305 mode = mode_show;
306 break;
307 }
308 /*FALLTHRU*/
309 case ARG_NOSHOW:
310 if (mode == mode_show)
311 mode = mode_compose;
312 break;
313
314 case ARG_STORE:
315 if (is_true (arg))
316 {
317 mode = mode_store;
318 break;
319 }
320 /*FALLTHRU*/
321 case ARG_NOSTORE:
322 if (mode == mode_store)
323 mode = mode_compose;
324 break;
325
326 /* List options */
327 case ARG_HEADER:
328 if (is_true (arg))
329 {
330 mode_options |= OPT_HEADERS;
331 break;
332 }
333 /*FALLTHRU*/
334 case ARG_NOHEADERS:
335 mode_options &= ~OPT_HEADERS;
336 break;
337
338 case ARG_REALSIZE:
339 if (is_true (arg))
340 {
341 mode_options |= OPT_REALSIZE;
342 break;
343 }
344 /*FALLTHRU*/
345 case ARG_NOREALSIZE:
346 mode_options &= ~OPT_REALSIZE;
347 break;
348
349 /* Display options */
350
351 case ARG_SERIALONLY:
352 mh_opt_notimpl_warning ("-[no]serialonly");
353 if (is_true (arg))
354 {
355 mode_options |= OPT_SERIALONLY;
356 break;
357 }
358 /*FALLTHRU*/
359 case ARG_NOSERIALONLY:
360 mode_options &= ~OPT_SERIALONLY;
361 break;
362
363 case ARG_PAUSE:
364 pause_option = is_true (arg);
365 break;
366
367 case ARG_NOPAUSE:
368 pause_option = 0;
369 break;
370
371 /* Store options */
372 case ARG_AUTO:
373 if (is_true (arg))
374 {
375 mode_options |= OPT_AUTO;
376 break;
377 }
378 /*FALLTHRU*/
379 case ARG_NOAUTO:
380 mode_options &= ~OPT_AUTO;
381 break;
382
383 case ARG_FORM:
384 mh_find_file (arg, &formfile);
385 break;
386
387 /* Common options */
388 case ARG_VERBOSE:
389 if (is_true (arg))
390 {
391 mode_options |= OPT_VERBOSE;
392 break;
393 }
394 /*FALLTHRU*/
395 case ARG_NOVERBOSE:
396 mode_options &= ~OPT_VERBOSE;
397 break;
398 173
399 case ARG_TYPE: 174 static void
175 set_type (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
176 {
400 sfree (&content_type); 177 sfree (&content_type);
401 sfree (&content_subtype); 178 sfree (&content_subtype);
402 split_content (arg, &content_type, &content_subtype); 179 split_content (arg, &content_type, &content_subtype);
403 break;
404
405 case ARG_PART:
406 req_part = msg_part_parse (arg);
407 break;
408
409 case ARG_QUIET:
410 mode_options |= OPT_QUIET;
411 break;
412
413 case ARG_CHARSET:
414 charset = arg;
415 break;
416
417 case ARGP_KEY_FINI:
418 if (!formfile)
419 mh_find_file ("mhl.headers", &formfile);
420 if (!isatty (0))
421 pause_option = 0;
422 break;
423
424 default:
425 return ARGP_ERR_UNKNOWN;
426 }
427 return 0;
428 } 180 }
429 181
182 static struct mu_option options[] = {
183 { "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
184 N_("specify folder to operate upon"),
185 mu_c_string, NULL, mh_opt_set_folder },
186 { "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
187 N_("specify file to operate upon"),
188 mu_c_string, &input_file },
189
190 MU_OPTION_GROUP (N_("MIME editing options")),
191 { "compose", 0, NULL, MU_OPTION_DEFAULT,
192 N_("compose the MIME message (default)"),
193 mu_c_bool, &compose_option },
194 { "build", 0, NULL, MU_OPTION_ALIAS },
195
196 MU_OPTION_GROUP (N_("Listing options")),
197 { "list", 0, NULL, MU_OPTION_DEFAULT,
198 N_("list the table of contents"),
199 mu_c_bool, &list_option },
200 { "headers", 0, NULL, MU_OPTION_DEFAULT,
201 N_("print the banner above the listing"),
202 mu_c_bool, &headers_option },
203 { "realsize", 0, NULL, MU_OPTION_DEFAULT,
204 N_("list the decoded sizes"),
205 mu_c_bool, &realsize_option },
206
207 MU_OPTION_GROUP (N_("Display options")),
208 { "show", 0, NULL, MU_OPTION_DEFAULT,
209 N_("display the contents of the messages"),
210 mu_c_bool, &show_option },
211 { "serialonly", 0, NULL, MU_OPTION_HIDDEN,
212 "",
213 mu_c_bool, NULL, mh_opt_notimpl_warning },
214 { "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
215 N_("read mhl format from FILE"),
216 mu_c_string, &formfile, mh_opt_find_file },
217 { "pause", 0, NULL, MU_OPTION_DEFAULT,
218 N_("pause prior to displaying content"),
219 mu_c_bool, &pause_option },
220
221 MU_OPTION_GROUP (N_("Saving options")),
222 { "store", 0, NULL, MU_OPTION_DEFAULT,
223 N_("write extracted message parts to disk"),
224 mu_c_bool, &store_option },
225 { "auto", 0, NULL, MU_OPTION_DEFAULT,
226 N_("use filenames from the content headers"),
227 mu_c_bool, &auto_option },
228 { "charset", 0, N_("NAME"), MU_OPTION_DEFAULT,
229 N_("use this charset to represent attachment file names"),
230 mu_c_string, &charset },
231
232 MU_OPTION_GROUP (N_("Other options")),
233 { "part", 0, N_("PART"), MU_OPTION_DEFAULT,
234 N_("limit the scope of the operation to the given part"),
235 mu_c_string, NULL, set_part },
236 { "type", 0, N_("CONTENT"), MU_OPTION_DEFAULT,
237 N_("operate on message part with given multipart content"),
238 mu_c_string, NULL, set_type },
239 { "verbose", 0, NULL, MU_OPTION_DEFAULT,
240 N_("print additional information"),
241 mu_c_bool, &verbose_option },
242 { "quiet", 0, NULL, MU_OPTION_DEFAULT,
243 N_("be quiet"),
244 mu_c_bool, &quiet_option },
245
246 MU_OPTION_END
247 };
248
430 249
431 /* *********************** Message part functions ************************* */ 250 /* *********************** Message part functions ************************* */
432 251
...@@ -555,7 +374,7 @@ msg_part_format_pool (mu_opool_t pool, msg_part_t p) ...@@ -555,7 +374,7 @@ msg_part_format_pool (mu_opool_t pool, msg_part_t p)
555 } 374 }
556 375
557 msg_part_t 376 msg_part_t
558 msg_part_parse (char *str) 377 msg_part_parse (char const *str)
559 { 378 {
560 msg_part_t p = msg_part_create (0); 379 msg_part_t p = msg_part_create (0);
561 380
...@@ -1267,7 +1086,7 @@ mhn_message_size (mu_message_t msg, mu_off_t *psize) ...@@ -1267,7 +1086,7 @@ mhn_message_size (mu_message_t msg, mu_off_t *psize)
1267 1086
1268 *psize = 0; 1087 *psize = 0;
1269 mu_message_get_body (msg, &body); 1088 mu_message_get_body (msg, &body);
1270 if (mode_options & OPT_REALSIZE) 1089 if (realsize_option)
1271 { 1090 {
1272 mu_stream_t dstr = NULL, bstr = NULL; 1091 mu_stream_t dstr = NULL, bstr = NULL;
1273 1092
...@@ -1389,7 +1208,7 @@ mhn_list () ...@@ -1389,7 +1208,7 @@ mhn_list ()
1389 { 1208 {
1390 int rc; 1209 int rc;
1391 1210
1392 if (mode_options & OPT_HEADERS) 1211 if (headers_option)
1393 printf (_(" msg part type/subtype size description\n")); 1212 printf (_(" msg part type/subtype size description\n"));
1394 1213
1395 if (message) 1214 if (message)
...@@ -1672,7 +1491,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, ...@@ -1672,7 +1491,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
1672 if (mu_message_is_multipart (msg, &ismime) == 0 && ismime) 1491 if (mu_message_is_multipart (msg, &ismime) == 0 && ismime)
1673 return 0; 1492 return 0;
1674 1493
1675 if (mode_options & OPT_AUTO) 1494 if (auto_option)
1676 { 1495 {
1677 char *val; 1496 char *val;
1678 int rc = mu_message_aget_decoded_attachment_name (msg, charset, 1497 int rc = mu_message_aget_decoded_attachment_name (msg, charset,
...@@ -1773,7 +1592,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, ...@@ -1773,7 +1592,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
1773 printf (_("storing message %s part %s as file %s\n"), 1592 printf (_("storing message %s part %s as file %s\n"),
1774 prefix, partstr, name); 1593 prefix, partstr, name);
1775 1594
1776 if (!(mode_options & OPT_QUIET) && access (name, R_OK) == 0) 1595 if (!quiet_option && access (name, R_OK) == 0)
1777 { 1596 {
1778 int ok; 1597 int ok;
1779 1598
...@@ -2939,16 +2758,17 @@ int ...@@ -2939,16 +2758,17 @@ int
2939 main (int argc, char **argv) 2758 main (int argc, char **argv)
2940 { 2759 {
2941 int rc; 2760 int rc;
2942 int index;
2943 2761
2944 MU_APP_INIT_NLS (); 2762 MU_APP_INIT_NLS ();
2945 2763
2946 mh_argp_init (); 2764 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
2947 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, 2765 if (!formfile)
2948 opt_handler, NULL, &index); 2766 mh_find_file ("mhl.headers", &formfile);
2767 if (!isatty (0))
2768 pause_option = 0;
2949 2769
2950 argc -= index; 2770 if (!compose_option && !list_option && !show_option && !store_option)
2951 argv += index; 2771 show_option = 1;
2952 2772
2953 signal (SIGPIPE, SIG_IGN); 2773 signal (SIGPIPE, SIG_IGN);
2954 2774
...@@ -2966,45 +2786,36 @@ main (int argc, char **argv) ...@@ -2966,45 +2786,36 @@ main (int argc, char **argv)
2966 if (!message) 2786 if (!message)
2967 return 1; 2787 return 1;
2968 } 2788 }
2969 else if (mode == mode_compose) 2789
2790 if (compose_option)
2970 { 2791 {
2971 if (argc > 1) 2792 if (argc > 1)
2972 { 2793 {
2973 mu_error (_("extra arguments")); 2794 mu_error (_("extra arguments"));
2974 return 1; 2795 return 1;
2975 } 2796 }
2797 if (!input_file)
2798 {
2976 input_file = mh_expand_name (mu_folder_directory (), 2799 input_file = mh_expand_name (mu_folder_directory (),
2977 argc == 1 ? argv[0] : "draft", NAME_ANY); 2800 argc == 1
2801 ? argv[0] : "draft", NAME_ANY);
2978 message = mh_file_to_message (NULL, input_file); 2802 message = mh_file_to_message (NULL, input_file);
2979 if (!message) 2803 if (!message)
2980 return 1; 2804 return 1;
2981 } 2805 }
2806 rc = mhn_compose ();
2807 }
2982 else 2808 else
2983 { 2809 {
2984 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); 2810 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
2985 mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); 2811 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
2986 } 2812 /* FIXME: Combine the three */
2987 2813 if (list_option)
2988 switch (mode)
2989 {
2990 case mode_compose:
2991 rc = mhn_compose ();
2992 break;
2993
2994 case mode_list:
2995 rc = mhn_list (); 2814 rc = mhn_list ();
2996 break; 2815 if (show_option)
2997 2816 rc |= mhn_show ();
2998 case mode_show: 2817 if (store_option)
2999 rc = mhn_show (); 2818 rc |= mhn_store ();
3000 break;
3001
3002 case mode_store:
3003 rc = mhn_store ();
3004 break;
3005
3006 default:
3007 abort ();
3008 } 2819 }
3009 return rc ? 1 : 0; 2820 return rc ? 1 : 0;
3010 } 2821 }
......
...@@ -19,47 +19,21 @@ ...@@ -19,47 +19,21 @@
19 19
20 #include <mh.h> 20 #include <mh.h>
21 21
22 static char doc[] = N_("GNU MH mhparam")"\v" 22 static char prog_doc[] = N_("GNU MH mhparam");
23 N_("Use -help to obtain the list of traditional MH options.");
24 static char args_doc[] = N_("[COMPONENT [COMPONENT...]]"); 23 static char args_doc[] = N_("[COMPONENT [COMPONENT...]]");
25 24
26 /* GNU options */
27 static struct argp_option options[] = {
28 {"all", ARG_ALL, NULL, 0,
29 N_("display all components from the MH profile. All other arguments are ignored")},
30 {"component", ARG_COMPONENT, N_("BOOL"), OPTION_ARG_OPTIONAL,
31 N_("always display the component name") },
32 { 0 }
33 };
34
35 /* Traditional MH options */
36 struct mh_option mh_option[] = {
37 { "all" },
38 { "component", MH_OPT_BOOL },
39 { NULL }
40 };
41
42 static int display_all; 25 static int display_all;
43 static int display_comp_name = -1; 26 static int display_comp_name = -1;
44 27
45 static error_t 28 static struct mu_option options[] = {
46 opt_handler (int key, char *arg, struct argp_state *state) 29 { "all", 0, NULL, MU_OPTION_DEFAULT,
47 { 30 N_("display all components from the MH profile. All other arguments are ignored"),
48 switch (key) 31 mu_c_bool, &display_all },
49 { 32 { "component", 0, NULL, MU_OPTION_DEFAULT,
50 case ARG_ALL: 33 N_("always display the component name"),
51 display_all = 1; 34 mu_c_bool, &display_comp_name },
52 break; 35 MU_OPTION_END
53 36 };
54 case ARG_COMPONENT:
55 display_comp_name = is_true (arg);
56 break;
57
58 default:
59 return ARGP_ERR_UNKNOWN;
60 }
61 return 0;
62 }
63 37
64 static struct { 38 static struct {
65 char *comp; 39 char *comp;
...@@ -81,7 +55,8 @@ mhparam_defval (char *comp) ...@@ -81,7 +55,8 @@ mhparam_defval (char *comp)
81 } 55 }
82 56
83 int 57 int
84 mhparam_iterator (const char *comp, const char *value, void *data MU_ARG_UNUSED) 58 mhparam_iterator (const char *comp, const char *value,
59 void *data MU_ARG_UNUSED)
85 { 60 {
86 if (display_comp_name) 61 if (display_comp_name)
87 printf("%s:\t", comp); 62 printf("%s:\t", comp);
...@@ -112,14 +87,10 @@ mhparam (char *comp) ...@@ -112,14 +87,10 @@ mhparam (char *comp)
112 int 87 int
113 main (int argc, char **argv) 88 main (int argc, char **argv)
114 { 89 {
115 int index;
116
117 /* Native Language Support */ 90 /* Native Language Support */
118 MU_APP_INIT_NLS (); 91 MU_APP_INIT_NLS ();
119 92
120 mh_argp_init (); 93 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
121 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
122 opt_handler, NULL, &index);
123 94
124 if (display_all) 95 if (display_all)
125 { 96 {
...@@ -129,11 +100,13 @@ main (int argc, char **argv) ...@@ -129,11 +100,13 @@ main (int argc, char **argv)
129 } 100 }
130 else 101 else
131 { 102 {
103 int i;
104
132 if (display_comp_name == -1) 105 if (display_comp_name == -1)
133 display_comp_name = argc - index > 1; 106 display_comp_name = argc > 1;
134 107
135 for (; index < argc; index++) 108 for (i = 0; i < argc; i++)
136 mhparam (argv[index]); 109 mhparam (argv[i]);
137 } 110 }
138 return 0; 111 return 0;
139 } 112 }
......
...@@ -19,37 +19,9 @@ ...@@ -19,37 +19,9 @@
19 19
20 #include <mh.h> 20 #include <mh.h>
21 21
22 static char doc[] = N_("GNU MH mhpath")"\v" 22 static char prog_doc[] = N_("GNU MH mhpath");
23 N_("Use -help to obtain the list of traditional MH options.");
24 static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); 23 static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
25 24
26 /* GNU options */
27 static struct argp_option options[] = {
28 {"folder", ARG_FOLDER, N_("FOLDER"), 0,
29 N_("specify folder to operate upon")},
30 { 0 }
31 };
32
33 /* Traditional MH options */
34 struct mh_option mh_option[] = {
35 { NULL }
36 };
37
38 static error_t
39 opt_handler (int key, char *arg, struct argp_state *state)
40 {
41 switch (key)
42 {
43 case ARG_FOLDER:
44 mh_set_current_folder (arg);
45 break;
46
47 default:
48 return ARGP_ERR_UNKNOWN;
49 }
50 return 0;
51 }
52
53 static int 25 static int
54 mhpath (size_t num, mu_message_t msg, void *data) 26 mhpath (size_t num, mu_message_t msg, void *data)
55 { 27 {
...@@ -63,7 +35,6 @@ mhpath (size_t num, mu_message_t msg, void *data) ...@@ -63,7 +35,6 @@ mhpath (size_t num, mu_message_t msg, void *data)
63 int 35 int
64 main (int argc, char **argv) 36 main (int argc, char **argv)
65 { 37 {
66 int index = 0;
67 mu_mailbox_t mbox = NULL; 38 mu_mailbox_t mbox = NULL;
68 mu_url_t url = NULL; 39 mu_url_t url = NULL;
69 char *mhdir; 40 char *mhdir;
...@@ -75,9 +46,8 @@ main (int argc, char **argv) ...@@ -75,9 +46,8 @@ main (int argc, char **argv)
75 /* Native Language Support */ 46 /* Native Language Support */
76 MU_APP_INIT_NLS (); 47 MU_APP_INIT_NLS ();
77 48
78 mh_argp_init (); 49 mh_getopt (&argc, &argv, NULL, MH_GETOPT_DEFAULT_FOLDER,
79 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, 50 args_doc, prog_doc, NULL);
80 opt_handler, NULL, &index);
81 51
82 current_folder = mh_current_folder (); 52 current_folder = mh_current_folder ();
83 /* If the only argument is `+', your MH Path is output; this 53 /* If the only argument is `+', your MH Path is output; this
...@@ -98,7 +68,7 @@ main (int argc, char **argv) ...@@ -98,7 +68,7 @@ main (int argc, char **argv)
98 68
99 /* If no `msgs' are specified, mhpath outputs the folder pathname 69 /* If no `msgs' are specified, mhpath outputs the folder pathname
100 instead. */ 70 instead. */
101 if (index == argc) 71 if (argc == 0)
102 { 72 {
103 printf ("%s\n", mhdir); 73 printf ("%s\n", mhdir);
104 exit (0); 74 exit (0);
...@@ -112,7 +82,7 @@ main (int argc, char **argv) ...@@ -112,7 +82,7 @@ main (int argc, char **argv)
112 The "new" message may not be used as part of a message 82 The "new" message may not be used as part of a message
113 range. */ 83 range. */
114 84
115 if (argc - index == 1 && strcmp (argv[index], "new") == 0) 85 if (argc == 1 && strcmp (argv[0], "new") == 0)
116 { 86 {
117 mu_message_t msg = NULL; 87 mu_message_t msg = NULL;
118 size_t num; 88 size_t num;
...@@ -126,7 +96,7 @@ main (int argc, char **argv) ...@@ -126,7 +96,7 @@ main (int argc, char **argv)
126 /* Mhpath expands and sorts the message list `msgs' and 96 /* Mhpath expands and sorts the message list `msgs' and
127 writes the full pathnames of the messages to the standard 97 writes the full pathnames of the messages to the standard
128 output separated by newlines. */ 98 output separated by newlines. */
129 mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur"); 99 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
130 status = mu_msgset_foreach_message (msgset, mhpath, mhdir); 100 status = mu_msgset_foreach_message (msgset, mhpath, mhdir);
131 mu_mailbox_close (mbox); 101 mu_mailbox_close (mbox);
132 mu_mailbox_destroy (&mbox); 102 mu_mailbox_destroy (&mbox);
......
...@@ -18,50 +18,20 @@ ...@@ -18,50 +18,20 @@
18 18
19 #include <mh.h> 19 #include <mh.h>
20 20
21 static char doc[] = N_("GNU MH mhseq")"\v" 21 static char prog_doc[] = N_("GNU MH mhseq");
22 N_("Use -help to obtain the list of traditional MH options.");
23 static char args_doc[] = N_("[SEQUENCE]"); 22 static char args_doc[] = N_("[SEQUENCE]");
24 23
25 static struct argp_option options[] = {
26 {"folder", ARG_FOLDER, N_("FOLDER"), 0,
27 N_("specify the folder to use")},
28 { "uids", 'u', NULL, 0,
29 N_("show message UIDs (default)")},
30 { "numbers", 'n', NULL, 0,
31 N_("show message numbers") },
32 { NULL }
33 };
34
35 /* Traditional MH options */
36 struct mh_option mh_option[] = {
37 { "uid" },
38 { NULL }
39 };
40
41 static int uid_option = 1; 24 static int uid_option = 1;
42 25
43 static error_t 26 static struct mu_option options[] = {
44 opt_handler (int key, char *arg, struct argp_state *state) 27 { "uids", 0, NULL, MU_OPTION_DEFAULT,
45 { 28 N_("show message UIDs (default)"),
46 switch (key) 29 mu_c_int, &uid_option, NULL, "1" },
47 { 30 { "numbers", 0, NULL, MU_OPTION_DEFAULT,
48 case ARG_FOLDER: 31 N_("show message numbers"),
49 mh_set_current_folder (arg); 32 mu_c_int, &uid_option, NULL, "0" },
50 break; 33 MU_OPTION_END
51 34 };
52 case 'n':
53 uid_option = 0;
54 break;
55
56 case 'u':
57 uid_option = 1;
58 break;
59
60 default:
61 return ARGP_ERR_UNKNOWN;
62 }
63 return 0;
64 }
65 35
66 static int 36 static int
67 _print_number (size_t n, void *data) 37 _print_number (size_t n, void *data)
...@@ -73,19 +43,15 @@ _print_number (size_t n, void *data) ...@@ -73,19 +43,15 @@ _print_number (size_t n, void *data)
73 int 43 int
74 main (int argc, char **argv) 44 main (int argc, char **argv)
75 { 45 {
76 int index;
77 mu_mailbox_t mbox; 46 mu_mailbox_t mbox;
78 mu_msgset_t msgset; 47 mu_msgset_t msgset;
79 48
80 /* Native Language Support */ 49 /* Native Language Support */
81 MU_APP_INIT_NLS (); 50 MU_APP_INIT_NLS ();
82 51
83 mh_argp_init (); 52 mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
84 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, 53 args_doc, prog_doc, NULL);
85 opt_handler, NULL, &index);
86 54
87 argc -= index;
88 argv += index;
89 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ); 55 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
90 56
91 mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); 57 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
......
...@@ -21,42 +21,9 @@ ...@@ -21,42 +21,9 @@
21 #include "mailutils/datetime.h" 21 #include "mailutils/datetime.h"
22 #include <pwd.h> 22 #include <pwd.h>
23 23
24 static char doc[] = N_("GNU MH msgchk")"\v" 24 static char prog_doc[] = N_("GNU MH msgchk");
25 N_("Use -help to obtain the list of traditional MH options.");
26 static char args_doc[] = N_("USER [USER...]"); 25 static char args_doc[] = N_("USER [USER...]");
27 26
28 /* GNU options */
29 static struct argp_option options[] = {
30 {"date", ARG_DATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
31 N_("print out the last date mail was read") },
32 {"nodate", ARG_NODATE, NULL, OPTION_HIDDEN,
33 N_("don't print out the last date mail was read") },
34 {"notify", ARG_NOTIFY, "all|mail|nomail", 0,
35 N_("produce a message upon these events") },
36 {"nonotify", ARG_NONOTIFY, "all|mail|nomail", 0,
37 N_("disable notification") },
38 {"host", ARG_HOST, N_("URL"), 0,
39 N_("check mail on this host or URL") },
40 {"user", ARG_USER, N_("NAME"), 0,
41 N_("set user name for remote mailbox access") },
42 {"apop", ARG_APOP, N_("BOOL"), OPTION_ARG_OPTIONAL,
43 N_("enable APOP") },
44 {"noapop", ARG_NOAPOP, NULL, OPTION_HIDDEN,
45 N_("disable APOP") },
46 {NULL}
47 };
48
49 /* Traditional MH options */
50 struct mh_option mh_option[] = {
51 { "date", MH_OPT_BOOL },
52 { "notify", MH_OPT_ARG, "all|mail|nomail" },
53 { "nonotify", MH_OPT_ARG, "all|mail|nomail" },
54 { "host", MH_OPT_ARG, "host-or-url" },
55 { "user", MH_OPT_ARG, "name" },
56 { "apop", MH_OPT_BOOL },
57 { NULL }
58 };
59
60 int date_option = 1; 27 int date_option = 1;
61 int apop_option; 28 int apop_option;
62 char *remote_host; 29 char *remote_host;
...@@ -75,55 +42,53 @@ static struct mu_kwd notifytab[] = { ...@@ -75,55 +42,53 @@ static struct mu_kwd notifytab[] = {
75 { NULL } 42 { NULL }
76 }; 43 };
77 44
78 static error_t 45 static void
79 opt_handler (int key, char *arg, struct argp_state *state) 46 set_notify (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
80 { 47 {
81 int n; 48 int n;
82
83 switch (key)
84 {
85 case ARG_DATE:
86 date_option = is_true (arg);
87 break;
88
89 case ARG_NODATE:
90 date_option = 0;
91 break;
92
93 case ARG_APOP:
94 apop_option = is_true (arg);
95 break;
96
97 case ARG_NOAPOP:
98 apop_option = 0;
99 break;
100
101 case ARG_NOTIFY:
102 if (mu_kwd_xlat_name (notifytab, arg, &n)) 49 if (mu_kwd_xlat_name (notifytab, arg, &n))
103 argp_error (state, "unknown notify argument: %s", arg); 50 {
51 mu_parseopt_error (po, "unknown notify argument: %s", arg);
52 exit (po->po_exit_error);
53 }
104 notify |= n; 54 notify |= n;
105 break; 55 }
106 56
107 case ARG_NONOTIFY: 57 static void
58 clr_notify (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
59 {
60 int n;
108 if (mu_kwd_xlat_name (notifytab, arg, &n)) 61 if (mu_kwd_xlat_name (notifytab, arg, &n))
109 argp_error (state, "unknown notify argument: %s", arg); 62 {
110 notify &= ~n; 63 mu_parseopt_error (po, "unknown notify argument: %s", arg);
111 break; 64 exit (po->po_exit_error);
112
113 case ARG_USER:
114 remote_user = arg;
115 break;
116
117 case ARG_HOST:
118 remote_host = arg;
119 break;
120
121 default:
122 return ARGP_ERR_UNKNOWN;
123 } 65 }
124 return 0; 66 notify &= ~n;
125 } 67 }
126 68
69 static struct mu_option options[] = {
70 { "date", 0, NULL, MU_OPTION_DEFAULT,
71 N_("print out the last date mail was read"),
72 mu_c_bool, &date_option },
73 { "notify", 0, "all|mail|nomail", MU_OPTION_DEFAULT,
74 N_("produce a message upon these events"),
75 mu_c_string, NULL, set_notify },
76 { "nonotify", 0, "all|mail|nomail", MU_OPTION_DEFAULT,
77 N_("disable notification"),
78 mu_c_string, NULL, clr_notify },
79 { "host", 0, N_("URL"), MU_OPTION_DEFAULT,
80 N_("check mail on this host or URL"),
81 mu_c_string, &remote_host },
82 { "user", 0, N_("NAME"), MU_OPTION_DEFAULT,
83 N_("set user name for remote mailbox access"),
84 mu_c_string, &remote_user },
85 { "apop", 0, NULL, MU_OPTION_DEFAULT,
86 N_("enable APOP"),
87 mu_c_bool, &apop_option },
88
89 MU_OPTION_END
90 };
91
127 static char * 92 static char *
128 attach_auth_ticket (mu_mailbox_t mbox) 93 attach_auth_ticket (mu_mailbox_t mbox)
129 { 94 {
...@@ -185,7 +150,7 @@ checkmail (const char *username, int personal) ...@@ -185,7 +150,7 @@ checkmail (const char *username, int personal)
185 { 150 {
186 static mu_url_t pop_hint; 151 static mu_url_t pop_hint;
187 152
188 if (pop_hint) 153 if (!pop_hint)
189 { 154 {
190 rc = mu_url_create (&pop_hint, "pop://"); 155 rc = mu_url_create (&pop_hint, "pop://");
191 if (rc) 156 if (rc)
...@@ -382,17 +347,11 @@ checkmail (const char *username, int personal) ...@@ -382,17 +347,11 @@ checkmail (const char *username, int personal)
382 int 347 int
383 main (int argc, char **argv) 348 main (int argc, char **argv)
384 { 349 {
385 int index;
386 int rc = 0; 350 int rc = 0;
387 351
388 MU_APP_INIT_NLS (); 352 MU_APP_INIT_NLS ();
389 353
390 mh_argp_init (); 354 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
391 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
392 opt_handler, NULL, &index);
393
394 argc -= index;
395 argv += index;
396 355
397 if (argc == 0) 356 if (argc == 0)
398 { 357 {
......
...@@ -22,119 +22,11 @@ ...@@ -22,119 +22,11 @@
22 #include <pick.h> 22 #include <pick.h>
23 #include <pick-gram.h> 23 #include <pick-gram.h>
24 24
25 static char doc[] = N_("GNU MH pick")"\v" 25 static char prog_doc[] = N_("GNU MH pick");
26 N_("Compatibility syntax for picking a matching component is:\n\ 26 static char args_doc[] = N_("[--COMPONENT PATTERN]... [MSGLIST]");
27 \n\
28 --Component pattern\n\
29 \n\
30 where Component is the component name, containing at least one capital\n\
31 letter or followed by a colon, e.g.:\n\
32 \n\
33 --User-Agent Mailutils\n\
34 --user-agent: Mailutils\n\
35 \n\
36 Use -help to obtain a list of traditional MH options.");
37 static char args_doc[] = N_("[MSGLIST]");
38
39 /* GNU options */
40 static struct argp_option options[] = {
41 #define GRID 10
42 { "folder", ARG_FOLDER, N_("FOLDER"), 0,
43 N_("specify folder to operate upon"), GRID },
44 #undef GRID
45
46 #define GRID 20
47 { N_("Search patterns"), 0, NULL, OPTION_DOC, NULL, GRID },
48 { "component", ARG_COMPONENT, N_("FIELD"), 0,
49 N_("search the named header field"), GRID+1},
50 { "pattern", ARG_PATTERN, N_("STRING"), 0,
51 N_("set pattern to look for"), GRID+1 },
52 { "search", 0, NULL, OPTION_ALIAS, NULL, GRID+1 },
53 { "cflags", ARG_CFLAGS, N_("STRING"), 0,
54 N_("flags controlling the type of regular expressions. STRING must consist of one or more of the following letters: B=basic, E=extended, I=ignore case, C=case sensitive. Default is \"EI\". The flags remain in effect until the next occurrence of --cflags option. The option must occur right before --pattern or --component option (or its alias)."), GRID+1 },
55 { "cc", ARG_CC, N_("STRING"), 0,
56 N_("same as --component cc --pattern STRING"), GRID+1 },
57 { "date", ARG_DATE, N_("STRING"), 0,
58 N_("same as --component date --pattern STRING"), GRID+1 },
59 { "from", ARG_FROM, N_("STRING"), 0,
60 N_("same as --component from --pattern STRING"), GRID+1 },
61 { "subject", ARG_SUBJECT, N_("STRING"), 0,
62 N_("same as --component subject --pattern STRING"), GRID+1 },
63 { "to", ARG_TO, N_("STRING"), 0,
64 N_("same as --component to --pattern STRING"), GRID+1 },
65 #undef GRID
66
67 #define GRID 30
68 { N_("Date constraint operations"), 0, NULL, OPTION_DOC, NULL, GRID },
69 { "datefield",ARG_DATEFIELD, N_("STRING"), 0,
70 N_("search in the named date header field (default is `Date:')"), GRID+1 },
71 { "after", ARG_AFTER, N_("DATE"), 0,
72 N_("match messages after the given date"), GRID+1 },
73 { "before", ARG_BEFORE, N_("DATE"), 0,
74 N_("match messages before the given date"), GRID+1 },
75 #undef GRID
76
77 #define GRID 40
78 { N_("Logical operations and grouping"), 0, NULL, OPTION_DOC, NULL, GRID },
79 { "and", ARG_AND, NULL, 0,
80 N_("logical AND (default)"), GRID+1 },
81 { "or", ARG_OR, NULL, 0,
82 N_("logical OR"), GRID+1 },
83 { "not", ARG_NOT, NULL, 0,
84 N_("logical NOT"), GRID+1 },
85 { "lbrace", ARG_LBRACE, NULL, 0,
86 N_("open group"), GRID+1 },
87 { "(", 0, NULL, OPTION_ALIAS, NULL, GRID+1 },
88 { "rbrace", ARG_RBRACE, NULL, 0,
89 N_("close group"), GRID+1},
90 { ")", 0, NULL, OPTION_ALIAS, NULL, GRID+1 },
91 #undef GRID
92
93 #define GRID 50
94 { N_("Operations over the selected messages"), 0, NULL, OPTION_DOC, NULL,
95 GRID },
96 { "list", ARG_LIST, N_("BOOL"), OPTION_ARG_OPTIONAL,
97 N_("list the numbers of the selected messages (default)"), GRID+1 },
98 { "nolist", ARG_NOLIST, NULL, OPTION_HIDDEN, "", GRID+1 },
99 { "sequence", ARG_SEQUENCE, N_("NAME"), 0,
100 N_("add matching messages to the given sequence"), GRID+1 },
101 { "public", ARG_PUBLIC, N_("BOOL"), OPTION_ARG_OPTIONAL,
102 N_("create public sequence"), GRID+1 },
103 { "nopublic", ARG_NOPUBLIC, NULL, OPTION_HIDDEN, "", GRID+1 },
104 { "zero", ARG_ZERO, N_("BOOL"), OPTION_ARG_OPTIONAL,
105 N_("empty the sequence before adding messages"), GRID+1 },
106 { "nozero", ARG_NOZERO, NULL, OPTION_HIDDEN, "", GRID+1 },
107 #undef GRID
108
109 { NULL }
110 27
111 }; 28 static int public_option = 1;
112 29 static int zero_option = 0;
113 /* Traditional MH options */
114 struct mh_option mh_option[] = {
115 { "component", MH_OPT_ARG, "field" },
116 { "pattern", MH_OPT_ARG, "pattern" },
117 { "search", MH_OPT_ARG, "pattern" },
118 { "cc", MH_OPT_ARG, "pattern" },
119 { "date", MH_OPT_ARG, "pattern" },
120 { "from", MH_OPT_ARG, "pattern" },
121 { "subject", MH_OPT_ARG, "pattern" },
122 { "to", MH_OPT_ARG, "pattern" },
123 { "datefield", MH_OPT_ARG, "field" },
124 { "after", MH_OPT_ARG, "date" },
125 { "before", MH_OPT_ARG, "date" },
126 { "and" },
127 { "or" },
128 { "not" },
129 { "lbrace" },
130 { "rbrace" },
131
132 { "list", MH_OPT_BOOL },
133 { "sequence", MH_OPT_ARG, "name" },
134 { "public", MH_OPT_BOOL },
135 { "zero", MH_OPT_BOOL },
136 { NULL }
137 };
138 30
139 static int list = 1; 31 static int list = 1;
140 static int seq_flags = 0; /* Create public sequences; 32 static int seq_flags = 0; /* Create public sequences;
...@@ -146,138 +38,177 @@ static mu_list_t lexlist; /* List of input tokens */ ...@@ -146,138 +38,177 @@ static mu_list_t lexlist; /* List of input tokens */
146 static mu_msgset_t picked_message_uids; 38 static mu_msgset_t picked_message_uids;
147 39
148 static void 40 static void
149 add_sequence (char *name) 41 add_component_name (struct mu_parseopt *po, struct mu_option *opt,
42 char const *arg)
150 { 43 {
151 if (!seq_list && mu_list_create (&seq_list)) 44 pick_add_token (&lexlist, T_COMP, arg);
152 {
153 mu_error (_("cannot create sequence list"));
154 exit (1);
155 }
156 mu_list_append (seq_list, name);
157 } 45 }
158 46
159 static error_t 47 static void
160 opt_handler (int key, char *arg, struct argp_state *state) 48 add_component_pattern (struct mu_parseopt *po, struct mu_option *opt,
49 char const *arg)
161 { 50 {
162 switch (key)
163 {
164 case ARG_FOLDER:
165 mh_set_current_folder (arg);
166 break;
167
168 case ARG_SEQUENCE:
169 add_sequence (arg);
170 list = 0;
171 break;
172
173 case ARG_LIST:
174 list = is_true (arg);
175 break;
176
177 case ARG_NOLIST:
178 list = 0;
179 break;
180
181 case ARG_COMPONENT:
182 pick_add_token (&lexlist, T_COMP, arg);
183 break;
184
185 case ARG_PATTERN:
186 pick_add_token (&lexlist, T_STRING, arg);
187 break;
188
189 case ARG_CC:
190 pick_add_token (&lexlist, T_COMP, "cc");
191 pick_add_token (&lexlist, T_STRING, arg); 51 pick_add_token (&lexlist, T_STRING, arg);
192 break; 52 }
193
194 case ARG_DATE:
195 pick_add_token (&lexlist, T_COMP, "date");
196 pick_add_token (&lexlist, T_STRING, arg);
197 break;
198
199 case ARG_FROM:
200 pick_add_token (&lexlist, T_COMP, "from");
201 pick_add_token (&lexlist, T_STRING, arg);
202 break;
203 53
204 case ARG_SUBJECT: 54 static void
205 pick_add_token (&lexlist, T_COMP, "subject"); 55 add_cflags (struct mu_parseopt *po, struct mu_option *opt,
206 pick_add_token (&lexlist, T_STRING, arg); 56 char const *arg)
207 break; 57 {
58 pick_add_token (&lexlist, T_CFLAGS, arg);
59 }
208 60
209 case ARG_TO: 61 static void
210 pick_add_token (&lexlist, T_COMP, "to"); 62 add_comp_match (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
63 {
64 pick_add_token (&lexlist, T_COMP, opt->opt_default);
211 pick_add_token (&lexlist, T_STRING, arg); 65 pick_add_token (&lexlist, T_STRING, arg);
212 break; 66 }
213 67
214 case ARG_DATEFIELD: 68 static void
69 add_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
70 {
215 pick_add_token (&lexlist, T_DATEFIELD, arg); 71 pick_add_token (&lexlist, T_DATEFIELD, arg);
216 break; 72 }
217 73
218 case ARG_AFTER: 74 static void
75 add_after (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
76 {
219 pick_add_token (&lexlist, T_AFTER, NULL); 77 pick_add_token (&lexlist, T_AFTER, NULL);
220 pick_add_token (&lexlist, T_STRING, arg); 78 pick_add_token (&lexlist, T_STRING, arg);
221 break; 79 }
222 80
223 case ARG_BEFORE: 81 static void
82 add_before (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
83 {
224 pick_add_token (&lexlist, T_BEFORE, NULL); 84 pick_add_token (&lexlist, T_BEFORE, NULL);
225 pick_add_token (&lexlist, T_STRING, arg); 85 pick_add_token (&lexlist, T_STRING, arg);
226 break; 86 }
227 87
228 case ARG_AND: 88 static void
89 add_and (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
90 {
229 pick_add_token (&lexlist, T_AND, NULL); 91 pick_add_token (&lexlist, T_AND, NULL);
230 break; 92 }
231 93
232 case ARG_OR: 94 static void
95 add_or (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
96 {
233 pick_add_token (&lexlist, T_OR, NULL); 97 pick_add_token (&lexlist, T_OR, NULL);
234 break; 98 }
235 99
236 case ARG_NOT: 100 static void
101 add_not (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
102 {
237 pick_add_token (&lexlist, T_NOT, NULL); 103 pick_add_token (&lexlist, T_NOT, NULL);
238 break; 104 }
239 105
240 case ARG_LBRACE: 106 static void
107 add_lbrace (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
108 {
241 pick_add_token (&lexlist, T_LBRACE, NULL); 109 pick_add_token (&lexlist, T_LBRACE, NULL);
242 break; 110 }
243 111
244 case ARG_RBRACE: 112 static void
113 add_rbrace (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
114 {
245 pick_add_token (&lexlist, T_RBRACE, NULL); 115 pick_add_token (&lexlist, T_RBRACE, NULL);
246 break; 116 }
247
248 case ARG_CFLAGS:
249 pick_add_token (&lexlist, T_CFLAGS, arg);
250 break;
251
252 case ARG_PUBLIC:
253 if (is_true (arg))
254 seq_flags &= ~SEQ_PRIVATE;
255 else
256 seq_flags |= SEQ_PRIVATE;
257 break;
258
259 case ARG_NOPUBLIC:
260 seq_flags |= SEQ_PRIVATE;
261 break;
262
263 case ARG_ZERO:
264 if (is_true (arg))
265 seq_flags |= SEQ_ZERO;
266 else
267 seq_flags &= ~SEQ_ZERO;
268 break;
269
270 case ARG_NOZERO:
271 seq_flags &= ~SEQ_ZERO;
272 break;
273 117
274 default: 118 static void
275 return ARGP_ERR_UNKNOWN; 119 add_to_sequence (struct mu_parseopt *po, struct mu_option *opt,
120 char const *arg)
121 {
122 if (!seq_list && mu_list_create (&seq_list))
123 {
124 mu_error (_("cannot create sequence list"));
125 exit (1);
276 } 126 }
277 127 mu_list_append (seq_list, mu_strdup (arg));
278 return 0; 128 list = 0;
279 } 129 }
280 130
131 static struct mu_option options[] = {
132 MU_OPTION_GROUP (N_("Search patterns")),
133 { "component", 0, N_("FIELD"), MU_OPTION_DEFAULT,
134 N_("search the named header field"),
135 mu_c_string, NULL, add_component_name },
136 { "pattern", 0, N_("STRING"), MU_OPTION_DEFAULT,
137 N_("set pattern to look for"),
138 mu_c_string, NULL, add_component_pattern },
139 { "search", 0, NULL, MU_OPTION_ALIAS },
140 { "cflags", 0, N_("STRING"), MU_OPTION_DEFAULT,
141 N_("flags controlling the type of regular expressions. "
142 "STRING must consist of one or more of the following letters: "
143 "B=basic, E=extended, I=ignore case, C=case sensitive. "
144 "Default is \"EI\". The flags remain in effect until the next "
145 "occurrence of --cflags option. The option must occur right "
146 "before --pattern or --component option (or its alias)."),
147 mu_c_string, NULL, add_cflags },
148 { "cc", 0, N_("STRING"), MU_OPTION_DEFAULT,
149 N_("search for Cc matching STRING"),
150 mu_c_string, NULL, add_comp_match, "cc" },
151 { "date", 0, N_("STRING"), MU_OPTION_DEFAULT,
152 N_("search for Date matching STRING"),
153 mu_c_string, NULL, add_comp_match, "date" },
154 { "from", 0, N_("STRING"), MU_OPTION_DEFAULT,
155 N_("search for From matching STRING"),
156 mu_c_string, NULL, add_comp_match, "from" },
157 { "subject", 0, N_("STRING"), MU_OPTION_DEFAULT,
158 N_("search for Subject matching STRING"),
159 mu_c_string, NULL, add_comp_match, "subject" },
160 { "to", 0, N_("STRING"), MU_OPTION_DEFAULT,
161 N_("search for To matching STRING"),
162 mu_c_string, NULL, add_comp_match, "to" },
163
164 MU_OPTION_GROUP (N_("Date constraint operations")),
165 { "datefield", 0, N_("STRING"), MU_OPTION_DEFAULT,
166 N_("search in the named date header field (default is `Date:')"),
167 mu_c_string, NULL, add_datefield },
168 { "after", 0, N_("DATE"), MU_OPTION_DEFAULT,
169 N_("match messages after the given date"),
170 mu_c_string, NULL, add_after },
171 { "before", 0, N_("DATE"), MU_OPTION_DEFAULT,
172 N_("match messages before the given date"),
173 mu_c_string, NULL, add_before },
174
175 MU_OPTION_GROUP (N_("Logical operations and grouping")),
176 { "and", 0, NULL, MU_OPTION_DEFAULT,
177 N_("logical AND (default)"),
178 mu_c_string, NULL, add_and },
179 { "or", 0, NULL, MU_OPTION_DEFAULT,
180 N_("logical OR"),
181 mu_c_string, NULL, add_or },
182 { "not", 0, NULL, MU_OPTION_DEFAULT,
183 N_("logical NOT"),
184 mu_c_string, NULL, add_not },
185 { "lbrace", 0, NULL, MU_OPTION_DEFAULT,
186 N_("open group"),
187 mu_c_string, NULL, add_lbrace },
188 { "(", 0, NULL, MU_OPTION_ALIAS },
189 { "rbrace", 0, NULL, MU_OPTION_DEFAULT,
190 N_("close group"),
191 mu_c_string, NULL, add_rbrace },
192 { ")", 0, NULL, MU_OPTION_ALIAS },
193
194 MU_OPTION_GROUP (N_("Operations over the selected messages")),
195 { "list", 0, NULL, MU_OPTION_ALIAS,
196 N_("list the numbers of the selected messages (default)"),
197 mu_c_bool, &list },
198 { "sequence", 0, N_("NAME"), MU_OPTION_DEFAULT,
199 N_("add matching messages to the given sequence"),
200 mu_c_string, NULL, add_to_sequence },
201 { "public", 0, NULL, MU_OPTION_DEFAULT,
202 N_("create public sequence"),
203 mu_c_bool, &public_option },
204 { "zero", 0, NULL, MU_OPTION_DEFAULT,
205 N_("empty the sequence before adding messages"),
206 mu_c_bool, &zero_option },
207
208 MU_OPTION_END
209
210 };
211
281 static int 212 static int
282 pick_message (size_t num, mu_message_t msg, void *data) 213 pick_message (size_t num, mu_message_t msg, void *data)
283 { 214 {
...@@ -301,89 +232,56 @@ action_add (void *item, void *data) ...@@ -301,89 +232,56 @@ action_add (void *item, void *data)
301 return 0; 232 return 0;
302 } 233 }
303 234
304 void 235 static void
305 pick_help_hook (void) 236 parse_comp_match (int *pargc, char **argv)
306 { 237 {
307 printf ("\n"); 238 int i, j;
308 printf (_("To match another component, use:\n\n")); 239 int argc = *pargc;
309 printf (_(" --Component pattern\n\n"));
310 printf (_("Note, that the component name must either be capitalized,\n"
311 "or followed by a colon.\n"));
312 printf ("\n");
313 }
314
315 /* NOTICE: For compatibility with RAND MH we have to support
316 the following command line syntax:
317
318 --COMP STRING
319
320 where `COMP' may be any string and which is equivalent to
321 `--component FIELD --pattern STRING'. Obviously this is in conflict
322 with the usual GNU long options paradigm which requires that any
323 unrecognized long option produce an error. The following
324 compromise solution is used:
325
326 The arguments `--COMP STRING' is recognized as a component matching
327 request if any of the following conditions is met:
328 240
329 1. The word `COMP' contains at least one capital letter. E.g.: 241 for (i = j = 0; i < argc; i++)
330 242 {
331 --User-Agent Mailutils 243 if (strncmp (argv[i], "--", 2) == 0)
332 244 {
333 2. The word `COMP' ends with a colon, e.g.: 245 if (++i < argc)
334 246 {
335 --user-agent: Mailutils 247 pick_add_token (&lexlist, T_COMP, argv[i-1] + 2);
336 248 pick_add_token (&lexlist, T_STRING, argv[i]);
337 3. Standard input is not connected to a terminal. This is always 249 }
338 true when pick is invoked from mh-pick.el Emacs module. 250 else
339 */ 251 {
252 mu_error (_("%s: must be followed by a pattern"), argv[i-1]);
253 exit (1);
254 }
255 }
256 else
257 argv[j++] = argv[i];
258 }
259 argv[j] = NULL;
260 *pargc = j;
261 }
340 262
341 int 263 int
342 main (int argc, char **argv) 264 main (int argc, char **argv)
343 { 265 {
344 int status; 266 int status;
345 int index;
346 mu_mailbox_t mbox; 267 mu_mailbox_t mbox;
347 mu_msgset_t msgset; 268 mu_msgset_t msgset;
348 int interactive = mh_interactive_mode_p ();
349 269
350 MU_APP_INIT_NLS (); 270 MU_APP_INIT_NLS ();
351 271
352 for (index = 1; index < argc; index++) 272 mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
353 { 273 args_doc, prog_doc, NULL);
354 int colon = 0, cpos; 274
355 if (argv[index][0] == '-' && argv[index][1] == '-' && 275 parse_comp_match (&argc, argv);
356 !strchr (argv[index], '=') && 276
357 (!interactive ||
358 (colon = argv[index][cpos = strlen (argv[index]) - 1] == ':') ||
359 *mu_str_skip_class_comp (argv[index], MU_CTYPE_UPPER)) &&
360 index + 1 < argc)
361 {
362 if (colon)
363 {
364 cpos -= 2;
365 mu_asprintf (&argv[index], "--component=%*.*s", cpos, cpos,
366 argv[index] + 2);
367 }
368 else
369 mu_asprintf (&argv[index], "--component=%s", argv[index] + 2);
370 mu_asprintf (&argv[index + 1], "--pattern=%s", argv[index + 1]);
371 index++;
372 }
373 }
374 mh_help_hook = pick_help_hook;
375 mh_argp_init ();
376 mh_argp_parse (&argc, &argv, 0, options, mh_option,
377 args_doc, doc, opt_handler, NULL, &index);
378 if (pick_parse (lexlist)) 277 if (pick_parse (lexlist))
379 return 1; 278 return 1;
380 279
280 seq_flags = (public_option ? 0 : SEQ_PRIVATE) | (zero_option ? SEQ_ZERO : 0);
281
381 mbox = mh_open_folder (mh_current_folder (), 282 mbox = mh_open_folder (mh_current_folder (),
382 seq_list ? MU_STREAM_RDWR : MU_STREAM_READ); 283 seq_list ? MU_STREAM_RDWR : MU_STREAM_READ);
383 284
384 argc -= index;
385 argv += index;
386
387 if (seq_list) 285 if (seq_list)
388 mu_msgset_create (&picked_message_uids, NULL, MU_MSGSET_UID); 286 mu_msgset_create (&picked_message_uids, NULL, MU_MSGSET_UID);
389 287
......
...@@ -56,6 +56,6 @@ struct node ...@@ -56,6 +56,6 @@ struct node
56 } v; 56 } v;
57 }; 57 };
58 58
59 void pick_add_token (mu_list_t *list, int tok, char *val); 59 void pick_add_token (mu_list_t *list, int tok, char const *val);
60 int pick_parse (mu_list_t toklist); 60 int pick_parse (mu_list_t toklist);
61 int pick_eval (mu_message_t msg); 61 int pick_eval (mu_message_t msg);
......
...@@ -189,28 +189,28 @@ tokname (int tok) ...@@ -189,28 +189,28 @@ tokname (int tok)
189 switch (tok) 189 switch (tok)
190 { 190 {
191 case T_DATEFIELD: 191 case T_DATEFIELD:
192 return "--datefield"; 192 return "-datefield";
193 193
194 case T_BEFORE: 194 case T_BEFORE:
195 return "--before"; 195 return "-before";
196 196
197 case T_AFTER: 197 case T_AFTER:
198 return "--after"; 198 return "-after";
199 199
200 case T_LBRACE: 200 case T_LBRACE:
201 return "--lbrace"; 201 return "-lbrace";
202 202
203 case T_RBRACE: 203 case T_RBRACE:
204 return "--rbrace"; 204 return "-rbrace";
205 205
206 case T_OR: 206 case T_OR:
207 return "--or"; 207 return "-or";
208 208
209 case T_AND: 209 case T_AND:
210 return "--and"; 210 return "-and";
211 211
212 case T_NOT: 212 case T_NOT:
213 return "--not"; 213 return "-not";
214 } 214 }
215 return NULL; 215 return NULL;
216 } 216 }
...@@ -236,7 +236,7 @@ yyerror (const char *s) ...@@ -236,7 +236,7 @@ yyerror (const char *s)
236 } 236 }
237 237
238 void 238 void
239 pick_add_token (mu_list_t *list, int tok, char *val) 239 pick_add_token (mu_list_t *list, int tok, char const *val)
240 { 240 {
241 struct token *tp; 241 struct token *tp;
242 int rc; 242 int rc;
......
...@@ -19,98 +19,33 @@ ...@@ -19,98 +19,33 @@
19 #include <mh.h> 19 #include <mh.h>
20 #include "prompter.h" 20 #include "prompter.h"
21 21
22 static char doc[] = N_("GNU MH prompter")"\v" 22 static char prog_doc[] = N_("GNU MH prompter");
23 N_("Use -help to obtain the list of traditional MH options.");
24 static char args_doc[] = N_("FILE"); 23 static char args_doc[] = N_("FILE");
25 24
26 enum {
27 ARG_ERASE=256,
28 ARG_KILL,
29 ARG_PREPEND,
30 ARG_NOPREPEND,
31 ARG_RAPID,
32 ARG_NORAPID,
33 ARG_DOTEOF,
34 ARG_NODOTEOF
35 };
36
37 static struct argp_option options[] = {
38 { "erase", ARG_ERASE, N_("CHAR"), 0,
39 N_("set erase character") },
40 { "kill", ARG_KILL, N_("CHAR"), 0,
41 N_("set kill character") },
42 { "prepend", ARG_PREPEND, N_("BOOL"), 0,
43 N_("prepend user input to the message body") },
44 { "noprepend", ARG_NOPREPEND, NULL, OPTION_HIDDEN,
45 NULL },
46 { "rapid", ARG_RAPID, N_("BOOL"), 0,
47 N_("do not display message body") },
48 { "norapid", ARG_NORAPID, NULL, OPTION_HIDDEN,
49 NULL },
50 { "doteof", ARG_DOTEOF, N_("BOOL"), 0,
51 N_("a period on a line marks end-of-file") },
52 { "nodoteof", ARG_NODOTEOF, NULL, OPTION_HIDDEN,
53 NULL },
54 { NULL }
55 };
56
57 struct mh_option mh_option[] = {
58 { "erase", MH_OPT_ARG, "chr" },
59 { "kill", MH_OPT_ARG, "chr" },
60 { "prepend", MH_OPT_BOOL },
61 { "rapid", MH_OPT_BOOL },
62 { "doteof", MH_OPT_BOOL },
63 { NULL }
64 };
65
66 char *erase_seq; 25 char *erase_seq;
67 char *kill_seq; 26 char *kill_seq;
68 int prepend_option; 27 int prepend_option;
69 int rapid_option; 28 int rapid_option;
70 int doteof_option; 29 int doteof_option;
71 30
72 static error_t 31 static struct mu_option options[] = {
73 opt_handler (int key, char *arg, struct argp_state *state) 32 { "erase", 0, N_("CHAR"), MU_OPTION_DEFAULT,
74 { 33 N_("set erase character"),
75 switch (key) 34 mu_c_string, &erase_seq },
76 { 35 { "kill", 0, N_("CHAR"), MU_OPTION_DEFAULT,
77 case ARG_ERASE: 36 N_("set kill character"),
78 erase_seq = arg; 37 mu_c_string, &kill_seq },
79 break; 38 { "prepend", 0, NULL, MU_OPTION_DEFAULT,
80 39 N_("prepend user input to the message body"),
81 case ARG_KILL: 40 mu_c_bool, &prepend_option },
82 kill_seq = arg; 41 { "rapid", 0, NULL, MU_OPTION_DEFAULT,
83 break; 42 N_("do not display message body"),
84 43 mu_c_bool, &rapid_option },
85 case ARG_PREPEND: 44 { "doteof", 0, NULL, MU_OPTION_DEFAULT,
86 prepend_option = is_true (arg); 45 N_("a period on a line marks end-of-file"),
87 break; 46 mu_c_bool, &doteof_option },
88 47 MU_OPTION_END
89 case ARG_NOPREPEND: 48 };
90 prepend_option = 0;
91 break;
92
93 case ARG_RAPID:
94 rapid_option = is_true (arg);
95 break;
96
97 case ARG_NORAPID:
98 rapid_option = 0;
99 break;
100
101 case ARG_DOTEOF:
102 doteof_option = is_true (arg);
103 break;
104
105 case ARG_NODOTEOF:
106 doteof_option = 0;
107 break;
108
109 default:
110 return ARGP_ERR_UNKNOWN;
111 }
112 return 0;
113 }
114 49
115 static int 50 static int
116 is_empty_string (const char *str) 51 is_empty_string (const char *str)
...@@ -142,7 +77,6 @@ mu_stream_t strout; ...@@ -142,7 +77,6 @@ mu_stream_t strout;
142 int 77 int
143 main (int argc, char **argv) 78 main (int argc, char **argv)
144 { 79 {
145 int index;
146 int rc; 80 int rc;
147 mu_stream_t in, tmp; 81 mu_stream_t in, tmp;
148 mu_message_t msg; 82 mu_message_t msg;
...@@ -156,16 +90,20 @@ main (int argc, char **argv) ...@@ -156,16 +90,20 @@ main (int argc, char **argv)
156 90
157 MU_APP_INIT_NLS (); 91 MU_APP_INIT_NLS ();
158 92
159 mh_argp_init (); 93 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
160 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
161 opt_handler, NULL, &index);
162 94
163 if (index == argc) 95 if (argc == 0)
164 { 96 {
165 mu_error (_("file name not given")); 97 mu_error (_("file name not given"));
166 exit (1); 98 exit (1);
167 } 99 }
168 file = argv[index]; 100 else if (argc > 1)
101 {
102 mu_error (_("too many arguments"));
103 exit (1);
104 }
105
106 file = argv[0];
169 107
170 prompter_init (); 108 prompter_init ();
171 if (erase_seq) 109 if (erase_seq)
...@@ -186,7 +124,6 @@ main (int argc, char **argv) ...@@ -186,7 +124,6 @@ main (int argc, char **argv)
186 return 1; 124 return 1;
187 } 125 }
188 rc = mu_stream_to_message (in, &msg); 126 rc = mu_stream_to_message (in, &msg);
189 mu_stream_unref (in);
190 if (rc) 127 if (rc)
191 { 128 {
192 mu_error (_("input stream %s is not a message (%s)"), 129 mu_error (_("input stream %s is not a message (%s)"),
......
...@@ -23,39 +23,9 @@ ...@@ -23,39 +23,9 @@
23 #include <errno.h> 23 #include <errno.h>
24 #include <fcntl.h> 24 #include <fcntl.h>
25 25
26 static char doc[] = N_("GNU MH refile")"\v" 26 static char prog_doc[] = N_("GNU MH refile");
27 N_("Options marked with `*' are not yet implemented.\n\
28 Use -help to obtain the list of traditional MH options.");
29 static char args_doc[] = N_("MSGLIST FOLDER [FOLDER...]"); 27 static char args_doc[] = N_("MSGLIST FOLDER [FOLDER...]");
30 28
31 /* GNU options */
32 static struct argp_option options[] = {
33 {"folder", ARG_FOLDER, N_("FOLDER"), 0,
34 N_("specify folder to operate upon")},
35 {"draft", ARG_DRAFT, NULL, 0,
36 N_("use <mh-dir>/draft as the source message")},
37 {"copy", ARG_LINK, N_("BOOL"), OPTION_ARG_OPTIONAL,
38 N_("preserve the source folder copy")},
39 {"link", 0, NULL, OPTION_ALIAS, NULL},
40 {"preserve", ARG_PRESERVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
41 N_("* try to preserve message sequence numbers")},
42 {"source", ARG_SOURCE, N_("FOLDER"), 0,
43 N_("specify source folder; it will become the current folder after the program exits")},
44 {"src", 0, NULL, OPTION_ALIAS, NULL},
45 {"file", ARG_FILE, N_("FILE"), 0, N_("use FILE as the source message")},
46 { 0 }
47 };
48
49 /* Traditional MH options */
50 struct mh_option mh_option[] = {
51 { "file", MH_OPT_ARG, "input-file"},
52 { "draft" },
53 { "link", MH_OPT_BOOL },
54 { "preserve", MH_OPT_BOOL },
55 { "src", MH_OPT_ARG, "folder" },
56 { NULL }
57 };
58
59 int link_flag = 0; 29 int link_flag = 0;
60 int preserve_flag = 0; 30 int preserve_flag = 0;
61 char *source_file = NULL; 31 char *source_file = NULL;
...@@ -73,8 +43,39 @@ add_folder (const char *folder) ...@@ -73,8 +43,39 @@ add_folder (const char *folder)
73 mu_list_append (folder_name_list, mu_strdup (folder)); 43 mu_list_append (folder_name_list, mu_strdup (folder));
74 } 44 }
75 45
46 static void
47 add_folder_option (struct mu_parseopt *po, struct mu_option *opt,
48 const char *arg)
49 {
50 add_folder (arg);
51 }
52
53 static struct mu_option options[] = {
54 { "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
55 N_("specify folder to operate upon"),
56 mu_c_string, NULL, add_folder_option },
57 { "draft", 0, NULL, MU_OPTION_DEFAULT,
58 N_("use <mh-dir>/draft as the source message"),
59 mu_c_string, &source_file, NULL, "draft" },
60 { "copy", 0, NULL, MU_OPTION_DEFAULT,
61 N_("preserve the source folder copy"),
62 mu_c_bool, &link_flag },
63 { "link", 0, NULL, MU_OPTION_ALIAS },
64 { "preserve", 0, NULL, MU_OPTION_HIDDEN,
65 N_("try to preserve message sequence numbers"),
66 mu_c_string, NULL, mh_opt_notimpl_warning },
67 { "source", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
68 N_("specify source folder; it will become the current folder after the program exits"),
69 mu_c_string, NULL, mh_opt_set_folder },
70 { "src", 0, NULL, MU_OPTION_ALIAS },
71 { "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
72 N_("use FILE as the source message"),
73 mu_c_string, &source_file },
74 MU_OPTION_END
75 };
76
76 void 77 void
77 open_folders () 78 open_folders (void)
78 { 79 {
79 int rc; 80 int rc;
80 mu_iterator_t itr; 81 mu_iterator_t itr;
...@@ -139,47 +140,11 @@ _close_folder (void *unused, mu_mailbox_t mbox) ...@@ -139,47 +140,11 @@ _close_folder (void *unused, mu_mailbox_t mbox)
139 } 140 }
140 141
141 void 142 void
142 close_folders () 143 close_folders (void)
143 { 144 {
144 enumerate_folders (_close_folder, NULL); 145 enumerate_folders (_close_folder, NULL);
145 } 146 }
146 147
147 static int
148 opt_handler (int key, char *arg, struct argp_state *state)
149 {
150 switch (key)
151 {
152 case ARG_FOLDER:
153 add_folder (arg);
154 break;
155
156 case ARG_DRAFT:
157 source_file = "draft";
158 break;
159
160 case ARG_LINK:
161 link_flag = is_true(arg);
162 break;
163
164 case ARG_PRESERVE:
165 mh_opt_notimpl_warning ("-preserve");
166 preserve_flag = is_true(arg);
167 break;
168
169 case ARG_SOURCE:
170 mh_set_current_folder (arg);
171 break;
172
173 case ARG_FILE:
174 source_file = arg;
175 break;
176
177 default:
178 return ARGP_ERR_UNKNOWN;
179 }
180 return 0;
181 }
182
183 void 148 void
184 refile_folder (void *data, mu_mailbox_t mbox) 149 refile_folder (void *data, mu_mailbox_t mbox)
185 { 150 {
...@@ -216,7 +181,6 @@ refile_iterator (size_t num, mu_message_t msg, void *data) ...@@ -216,7 +181,6 @@ refile_iterator (size_t num, mu_message_t msg, void *data)
216 int 181 int
217 main (int argc, char **argv) 182 main (int argc, char **argv)
218 { 183 {
219 int index;
220 mu_msgset_t msgset; 184 mu_msgset_t msgset;
221 mu_mailbox_t mbox; 185 mu_mailbox_t mbox;
222 int status, i, j; 186 int status, i, j;
...@@ -224,13 +188,7 @@ main (int argc, char **argv) ...@@ -224,13 +188,7 @@ main (int argc, char **argv)
224 /* Native Language Support */ 188 /* Native Language Support */
225 MU_APP_INIT_NLS (); 189 MU_APP_INIT_NLS ();
226 190
227 mh_argp_init (); 191 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
228 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
229 opt_handler, NULL, &index);
230
231 argc -= index;
232 argv += index;
233
234 /* Collect any surplus folders */ 192 /* Collect any surplus folders */
235 for (i = j = 0; i < argc; i++) 193 for (i = j = 0; i < argc; i++)
236 { 194 {
......
...@@ -22,89 +22,9 @@ ...@@ -22,89 +22,9 @@
22 #include <sys/stat.h> 22 #include <sys/stat.h>
23 #include <unistd.h> 23 #include <unistd.h>
24 24
25 static char doc[] = N_("GNU MH repl")"\v" 25 static char prog_doc[] = N_("GNU MH repl");
26 N_("Options marked with `*' are not yet implemented.\n\
27 Use -help to obtain the list of traditional MH options.");
28 static char args_doc[] = N_("[+FOLDER] [MESSAGE]"); 26 static char args_doc[] = N_("[+FOLDER] [MESSAGE]");
29 27
30
31 /* GNU options */
32 static struct argp_option options[] = {
33 {"annotate", ARG_ANNOTATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
34 N_("add Replied: header to the message being replied to")},
35 {"build", ARG_BUILD, 0, 0,
36 N_("build the draft and quit immediately")},
37 {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
38 N_("specify the folder for message drafts")},
39 {"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0,
40 N_("undo the effect of the last --draftfolder option")},
41 {"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0,
42 N_("invoke the draftmessage facility")},
43 {"cc", ARG_CC, "{all|to|cc|me}", 0,
44 N_("specify whom to place on the Cc: list of the reply")},
45 {"nocc", ARG_NOCC, "{all|to|cc|me}", 0,
46 N_("specify whom to remove from the Cc: list of the reply")},
47 {"folder", ARG_FOLDER, N_("FOLDER"), 0, N_("specify folder to operate upon")},
48 {"group", ARG_GROUP, N_("BOOL"), OPTION_ARG_OPTIONAL,
49 N_("construct a group or followup reply") },
50 {"editor", ARG_EDITOR, N_("PROG"), 0, N_("set the editor program to use")},
51 {"noedit", ARG_NOEDIT, 0, 0, N_("suppress the initial edit")},
52 {"fcc", ARG_FCC, N_("FOLDER"), 0, N_("set the folder to receive Fcc's")},
53 {"filter", ARG_FILTER, N_("MHL-FILTER"), 0,
54 N_("set the mhl filter to preprocess the body of the message being replied")},
55 {"form", ARG_FORM, N_("FILE"), 0, N_("read format from given file")},
56 {"format", ARG_FORMAT, N_("BOOL"), OPTION_ARG_OPTIONAL,
57 N_("include a copy of the message being replied; the message will be processed using either the default filter \"mhl.reply\", or the filter specified by --filter option") },
58 {"noformat", ARG_NOFORMAT, 0, OPTION_HIDDEN, "" },
59 {"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL,
60 N_("* annotate the message in place")},
61 {"query", ARG_QUERY, N_("BOOL"), OPTION_ARG_OPTIONAL,
62 N_("* query for addresses to place in To: and Cc: lists")},
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, N_("use draft file preserved after the last session") },
69 { 0 }
70 };
71
72 /* Traditional MH options */
73 struct mh_option mh_option[] = {
74 { "annotate", MH_OPT_BOOL },
75 { "build" },
76 { "cc", MH_OPT_ARG, "all/to/cc/me"},
77 { "nocc", MH_OPT_ARG, "all/to/cc/me"},
78 { "form", MH_OPT_ARG, "formatfile"},
79 { "width", MH_OPT_ARG, "number"},
80 { "draftfolder", MH_OPT_ARG, "folder"},
81 { "nodraftfolder" },
82 { "draftmessage" },
83 { "editor", MH_OPT_ARG, "program"},
84 { "noedit" },
85 { "fcc", MH_OPT_ARG, "folder"},
86 { "filter", MH_OPT_ARG, "program"},
87 { "format", MH_OPT_BOOL },
88 { "group", MH_OPT_BOOL },
89 { "inplace", MH_OPT_BOOL },
90 { "query", MH_OPT_BOOL },
91 { "whatnowproc", MH_OPT_ARG, "program"},
92 { "nowhatnowproc" },
93 { NULL }
94 };
95
96 static char default_format_str[] =
97 "%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)"
98 "%<(nonnull)%(void(width))%(putaddr To: )\\n%>"
99 "%(lit)%<(rcpt to)%(formataddr{to})%>%<(rcpt cc)%(formataddr{cc})%>%<(rcpt me)%(formataddr(me))%>"
100 "%<(nonnull)%(void(width))%(putaddr cc: )\\n%>"
101 "%<{fcc}Fcc: %{fcc}\\n%>"
102 "%<{subject}Subject: Re: %(unre{subject})\\n%>"
103 "%(lit)%(concat(in_reply_to))%<(nonnull)%(void(width))%(printhdr In-reply-to: )\\n%>"
104 "%(lit)%(concat(references))%<(nonnull)%(void(width))%(printhdr References: )\\n%>"
105 "X-Mailer: MH \\(%(package_string)\\)\\n"
106 "--------\n";
107
108 static char *format_str = NULL; 28 static char *format_str = NULL;
109 static mh_format_t format; 29 static mh_format_t format;
110 static int width = 80; 30 static int width = 80;
...@@ -114,12 +34,11 @@ static int initial_edit = 1; ...@@ -114,12 +34,11 @@ static int initial_edit = 1;
114 static const char *whatnowproc; 34 static const char *whatnowproc;
115 static mu_msgset_t msgset; 35 static mu_msgset_t msgset;
116 static mu_mailbox_t mbox; 36 static mu_mailbox_t mbox;
117 static int build_only = 0; /* --build flag */ 37 static int build_only = 0; /* -build flag */
118 static int nowhatnowproc = 0; /* --nowhatnowproc */ 38 static int nowhatnowproc = 0; /* -nowhatnowproc */
119 static int query_mode = 0; /* --query flag */ 39 static int use_draft = 0; /* -use flag */
120 static int use_draft = 0; /* --use flag */ 40 static char *mhl_filter = NULL; /* -filter flag */
121 static char *mhl_filter = NULL; /* --filter flag */ 41 static int annotate; /* -annotate flag */
122 static int annotate; /* --annotate flag */
123 static char *draftmessage = "new"; 42 static char *draftmessage = "new";
124 static const char *draftfolder = NULL; 43 static const char *draftfolder = NULL;
125 static mu_opool_t fcc_pool; 44 static mu_opool_t fcc_pool;
...@@ -137,53 +56,43 @@ decode_cc_flag (const char *opt, const char *arg) ...@@ -137,53 +56,43 @@ decode_cc_flag (const char *opt, const char *arg)
137 return rc; 56 return rc;
138 } 57 }
139 58
140 static error_t 59 static void
141 opt_handler (int key, char *arg, struct argp_state *state) 60 set_cc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
142 { 61 {
143 switch (key)
144 {
145 case ARGP_KEY_INIT:
146 draftfolder = mh_global_profile_get ("Draft-Folder", NULL);
147 whatnowproc = mh_global_profile_get ("whatnowproc", NULL);
148 break;
149
150 case ARG_ANNOTATE:
151 annotate = is_true (arg);
152 break;
153
154 case ARG_BUILD:
155 build_only = 1;
156 break;
157
158 case ARG_CC:
159 rcpt_mask |= decode_cc_flag ("-cc", arg); 62 rcpt_mask |= decode_cc_flag ("-cc", arg);
160 break; 63 }
161 64
162 case ARG_NOCC: 65 static void
66 clr_cc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
67 {
163 rcpt_mask &= ~decode_cc_flag ("-nocc", arg); 68 rcpt_mask &= ~decode_cc_flag ("-nocc", arg);
164 break; 69 }
165
166 case ARG_DRAFTFOLDER:
167 draftfolder = arg;
168 break;
169
170 case ARG_EDITOR:
171 wh_env.editor = arg;
172 break;
173 70
174 case ARG_FOLDER: 71 static void
175 mh_set_current_folder (arg); 72 set_fcc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
176 break; 73 {
74 if (!has_fcc)
75 {
76 mu_opool_create (&fcc_pool, 1);
77 has_fcc = 1;
78 }
79 else
80 mu_opool_append (fcc_pool, ", ", 2);
81 mu_opool_appendz (fcc_pool, arg);
82 }
177 83
178 case ARG_FORM: 84 static void
179 free (format_str); 85 set_whatnowproc (struct mu_parseopt *po, struct mu_option *opt,
180 format_str = NULL; 86 char const *arg)
181 if (mh_read_formfile (arg, &format_str)) 87 {
182 exit (1); 88 whatnowproc = mu_strdup (arg);
183 break; 89 nowhatnowproc = 0;
90 }
184 91
185 case ARG_GROUP: 92 static void
186 if (is_true (arg)) 93 set_group (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
94 {
95 if (strcmp (arg, "1") == 0)
187 { 96 {
188 if (mh_read_formfile ("replgroupcomps", &format_str)) 97 if (mh_read_formfile ("replgroupcomps", &format_str))
189 exit (1); 98 exit (1);
...@@ -194,87 +103,87 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -194,87 +103,87 @@ opt_handler (int key, char *arg, struct argp_state *state)
194 free (format_str); 103 free (format_str);
195 format_str = NULL; 104 format_str = NULL;
196 } 105 }
197 break; 106 }
198
199 case ARG_DRAFTMESSAGE:
200 draftmessage = arg;
201 break;
202
203 case ARG_USE:
204 use_draft = is_true (arg);
205 break;
206
207 case ARG_WIDTH:
208 width = strtoul (arg, NULL, 0);
209 if (!width)
210 {
211 argp_error (state, _("invalid width"));
212 exit (1);
213 }
214 break;
215
216 case ARG_NODRAFTFOLDER:
217 draftfolder = NULL;
218 break;
219
220 case ARG_NOEDIT:
221 initial_edit = 0;
222 break;
223
224 case ARG_QUERY:
225 query_mode = is_true (arg);
226 if (query_mode)
227 mh_opt_notimpl_warning ("-query");
228 break;
229
230 case ARG_FILTER:
231 mh_find_file (arg, &mhl_filter);
232 break;
233
234 case ARG_FORMAT:
235 if (is_true (arg))
236 mh_find_file ("mhl.repl", &mhl_filter);
237 else
238 mhl_filter = NULL;
239 break;
240
241 case ARG_NOFORMAT:
242 mhl_filter = NULL;
243 break;
244
245 case ARG_FCC:
246 if (!has_fcc)
247 {
248 mu_opool_create (&fcc_pool, 1);
249 has_fcc = 1;
250 }
251 else
252 mu_opool_append (fcc_pool, ", ", 2);
253 mu_opool_appendz (fcc_pool, arg);
254 break;
255
256 case ARG_INPLACE:
257 mh_opt_notimpl_warning ("-inplace");
258 break;
259
260 case ARG_WHATNOWPROC:
261 whatnowproc = arg;
262 break;
263
264 case ARG_NOWHATNOWPROC:
265 nowhatnowproc = 1;
266 break;
267 107
268 case ARGP_KEY_FINI: 108 static struct mu_option options[] = {
269 if (!format_str) 109 { "annotate", 0, NULL, MU_OPTION_DEFAULT,
270 format_str = default_format_str; 110 N_("add Replied: header to the message being replied to"),
271 break; 111 mu_c_bool, &annotate },
112 { "build", 0, NULL, MU_OPTION_DEFAULT,
113 N_("build the draft and quit immediately"),
114 mu_c_bool, &build_only },
115 { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
116 N_("specify the folder for message drafts"),
117 mu_c_string, &draftfolder },
118 { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
119 N_("undo the effect of the last --draftfolder option"),
120 mu_c_string, &draftfolder, mh_opt_clear_string },
121 { "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT,
122 N_("invoke the draftmessage facility"),
123 mu_c_string, &draftmessage },
124 { "cc", 0, "{all|to|cc|me}", 0,
125 N_("specify whom to place on the Cc: list of the reply"),
126 mu_c_string, NULL, set_cc },
127 { "nocc", 0, "{all|to|cc|me}", 0,
128 N_("specify whom to remove from the Cc: list of the reply"),
129 mu_c_string, NULL, clr_cc },
130 { "group", 0, NULL, MU_OPTION_DEFAULT,
131 N_("construct a group or followup reply"),
132 mu_c_string, NULL, set_group },
133 { "editor", 0, N_("PROG"), MU_OPTION_DEFAULT,
134 N_("set the editor program to use"),
135 mu_c_string, &wh_env.editor },
136 { "noedit", 0, NULL, MU_OPTION_DEFAULT,
137 N_("suppress the initial edit"),
138 mu_c_int, &initial_edit, NULL, "0" },
139 { "fcc", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
140 N_("set the folder to receive Fcc's"),
141 mu_c_string, NULL, set_fcc },
142 { "filter", 0, N_("MHL-FILTER"), MU_OPTION_DEFAULT,
143 N_("set the mhl filter to preprocess the body of the message being replied"),
144 mu_c_string, &mhl_filter, mh_opt_find_file },
145 { "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
146 N_("read format from given file") ,
147 mu_c_string, &format_str, mh_opt_read_formfile },
148 { "format", 0, NULL, MU_OPTION_DEFAULT,
149 N_("include a copy of the message being replied; the message will be processed using either the default filter \"mhl.reply\", or the filter specified by --filter option"),
150 mu_c_string, &mhl_filter, mh_opt_find_file, "mhl.repl" },
151 { "noformat", 0, NULL, MU_OPTION_DEFAULT,
152 N_("cancels the effect of the recent -format option"),
153 mu_c_string, &mhl_filter, mh_opt_clear_string },
154 { "inplace", 0, NULL, MU_OPTION_HIDDEN,
155 N_("annotate the message in place"),
156 mu_c_string, NULL, mh_opt_notimpl_warning },
157 { "query", 0, NULL, MU_OPTION_HIDDEN,
158 N_("query for addresses to place in To: and Cc: lists"),
159 mu_c_string, NULL, mh_opt_notimpl_warning },
160 { "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
161 N_("set output width"),
162 mu_c_int, &width },
163 { "whatnowproc", 0, N_("PROG"), MU_OPTION_DEFAULT,
164 N_("set the replacement for whatnow program"),
165 mu_c_string, NULL, set_whatnowproc },
166 { "nowhatnowproc", 0, NULL, MU_OPTION_DEFAULT,
167 N_("don't run whatnowproc"),
168 mu_c_int, &nowhatnowproc, NULL, "1" },
169 { "use", 0, NULL, MU_OPTION_DEFAULT,
170 N_("use draft file preserved after the last session"),
171 mu_c_bool, &use_draft },
172
173 MU_OPTION_END
174 };
272 175
273 default: 176 static char default_format_str[] =
274 return ARGP_ERR_UNKNOWN; 177 "%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)"
275 } 178 "%<(nonnull)%(void(width))%(putaddr To: )\\n%>"
276 return 0; 179 "%(lit)%<(rcpt to)%(formataddr{to})%>%<(rcpt cc)%(formataddr{cc})%>%<(rcpt me)%(formataddr(me))%>"
277 } 180 "%<(nonnull)%(void(width))%(putaddr cc: )\\n%>"
181 "%<{fcc}Fcc: %{fcc}\\n%>"
182 "%<{subject}Subject: Re: %(unre{subject})\\n%>"
183 "%(lit)%(concat(in_reply_to))%<(nonnull)%(void(width))%(printhdr In-reply-to: )\\n%>"
184 "%(lit)%(concat(references))%<(nonnull)%(void(width))%(printhdr References: )\\n%>"
185 "X-Mailer: MH \\(%(package_string)\\)\\n"
186 "--------\n";
278 187
279 void 188 void
280 make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh) 189 make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
...@@ -396,15 +305,20 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh) ...@@ -396,15 +305,20 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
396 int 305 int
397 main (int argc, char **argv) 306 main (int argc, char **argv)
398 { 307 {
399 int index, rc; 308 int rc;
400 309
401 /* Native Language Support */ 310 /* Native Language Support */
402 MU_APP_INIT_NLS (); 311 MU_APP_INIT_NLS ();
403 312
404 mh_argp_init (); 313 draftfolder = mh_global_profile_get ("Draft-Folder", NULL);
314 whatnowproc = mh_global_profile_get ("whatnowproc", NULL);
315
316 mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
317 args_doc, prog_doc, NULL);
318
319 if (!format_str)
320 format_str = default_format_str;
405 321
406 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
407 opt_handler, NULL, &index);
408 if (mh_format_parse (format_str, &format)) 322 if (mh_format_parse (format_str, &format))
409 { 323 {
410 mu_error (_("Bad format string")); 324 mu_error (_("Bad format string"));
...@@ -412,7 +326,7 @@ main (int argc, char **argv) ...@@ -412,7 +326,7 @@ main (int argc, char **argv)
412 } 326 }
413 327
414 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); 328 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
415 mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur"); 329 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
416 if (!mh_msgset_single_message (msgset)) 330 if (!mh_msgset_single_message (msgset))
417 { 331 {
418 mu_error (_("only one message at a time!")); 332 mu_error (_("only one message at a time!"));
......
...@@ -28,29 +28,9 @@ ...@@ -28,29 +28,9 @@
28 28
29 #include <dirent.h> 29 #include <dirent.h>
30 30
31 static char doc[] = N_("GNU MH rmf")"\v" 31 static char prog_doc[] = N_("GNU MH rmf");
32 N_("Use -help to obtain the list of traditional MH options.");
33 static char args_doc[] = N_("[+FOLDER]"); 32 static char args_doc[] = N_("[+FOLDER]");
34 33
35 /* GNU options */
36 static struct argp_option options[] = {
37 {"folder", ARG_FOLDER, N_("FOLDER"), 0,
38 N_("specify the folder to delete")},
39 {"interactive", ARG_INTERACTIVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
40 N_("interactive mode: ask for confirmation before removing each folder")},
41 {"nointeractive", ARG_NOINTERACTIVE, NULL, OPTION_HIDDEN, ""},
42 {"recursive", ARG_RECURSIVE, NULL, 0,
43 N_("recursively delete all subfolders")},
44 {"norecursive", ARG_NORECURSIVE, NULL, OPTION_HIDDEN, ""},
45 { 0 }
46 };
47
48 /* Traditional MH options */
49 struct mh_option mh_option[] = {
50 { "interactive", MH_OPT_BOOL },
51 { 0 }
52 };
53
54 int explicit_folder; /* Was the folder explicitly given */ 34 int explicit_folder; /* Was the folder explicitly given */
55 int interactive; /* Ask for confirmation before deleting */ 35 int interactive; /* Ask for confirmation before deleting */
56 int recursive; /* Recursively process all the sub-directories */ 36 int recursive; /* Recursively process all the sub-directories */
...@@ -59,38 +39,26 @@ static char *cur_folder_path; /* Full pathname of the current folder */ ...@@ -59,38 +39,26 @@ static char *cur_folder_path; /* Full pathname of the current folder */
59 static char *folder_name; /* Name of the (topmost) folder to be 39 static char *folder_name; /* Name of the (topmost) folder to be
60 deleted */ 40 deleted */
61 41
62 static error_t 42 static void
63 opt_handler (int key, char *arg, struct argp_state *state) 43 set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
64 { 44 {
65 switch (key)
66 {
67 case ARG_FOLDER:
68 explicit_folder = 1; 45 explicit_folder = 1;
69 folder_name = arg; 46 folder_name = mu_strdup (arg);
70 break;
71
72 case ARG_INTERACTIVE:
73 interactive = is_true (arg);
74 break;
75
76 case ARG_NOINTERACTIVE:
77 interactive = 0;
78 break;
79
80 case ARG_RECURSIVE:
81 recursive = is_true (arg);
82 break;
83
84 case ARG_NORECURSIVE:
85 recursive = 0;
86 break;
87
88 default:
89 return ARGP_ERR_UNKNOWN;
90 }
91 return 0;
92 } 47 }
93 48
49 static struct mu_option options[] = {
50 { "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
51 N_("specify the folder to delete"),
52 mu_c_string, NULL, set_folder },
53 { "interactive", 0, NULL, MU_OPTION_DEFAULT,
54 N_("interactive mode: ask for confirmation before removing each folder"),
55 mu_c_bool, &interactive },
56 { "recursive", 0, NULL, MU_OPTION_DEFAULT,
57 N_("recursively delete all subfolders"),
58 mu_c_bool, &recursive },
59 MU_OPTION_END
60 };
61
94 static char * 62 static char *
95 current_folder_path (void) 63 current_folder_path (void)
96 { 64 {
...@@ -185,9 +153,7 @@ main (int argc, char **argv) ...@@ -185,9 +153,7 @@ main (int argc, char **argv)
185 /* Native Language Support */ 153 /* Native Language Support */
186 MU_APP_INIT_NLS (); 154 MU_APP_INIT_NLS ();
187 155
188 mh_argp_init (); 156 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
189 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
190 opt_handler, NULL, NULL);
191 157
192 cur_folder_path = current_folder_path (); 158 cur_folder_path = current_folder_path ();
193 159
......
...@@ -19,37 +19,9 @@ ...@@ -19,37 +19,9 @@
19 19
20 #include <mh.h> 20 #include <mh.h>
21 21
22 static char doc[] = N_("GNU MH rmm")"\v" 22 static char prog_doc[] = N_("GNU MH rmm");
23 N_("Use -help to obtain the list of traditional MH options.");
24 static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); 23 static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
25 24
26 /* GNU options */
27 static struct argp_option options[] = {
28 {"folder", ARG_FOLDER, N_("FOLDER"), 0,
29 N_("specify folder to operate upon")},
30 { 0 }
31 };
32
33 /* Traditional MH options */
34 struct mh_option mh_option[] = {
35 { NULL }
36 };
37
38 static error_t
39 opt_handler (int key, char *arg, struct argp_state *state)
40 {
41 switch (key)
42 {
43 case ARG_FOLDER:
44 mh_set_current_folder (arg);
45 break;
46
47 default:
48 return ARGP_ERR_UNKNOWN;
49 }
50 return 0;
51 }
52
53 static int 25 static int
54 rmm (size_t num, mu_message_t msg, void *data) 26 rmm (size_t num, mu_message_t msg, void *data)
55 { 27 {
...@@ -79,7 +51,6 @@ rmseq (const char *name, const char *value, void *data) ...@@ -79,7 +51,6 @@ rmseq (const char *name, const char *value, void *data)
79 int 51 int
80 main (int argc, char **argv) 52 main (int argc, char **argv)
81 { 53 {
82 int index = 0;
83 mu_mailbox_t mbox; 54 mu_mailbox_t mbox;
84 mu_msgset_t msgset; 55 mu_msgset_t msgset;
85 int status; 56 int status;
...@@ -88,13 +59,12 @@ main (int argc, char **argv) ...@@ -88,13 +59,12 @@ main (int argc, char **argv)
88 /* Native Language Support */ 59 /* Native Language Support */
89 MU_APP_INIT_NLS (); 60 MU_APP_INIT_NLS ();
90 61
91 mh_argp_init (); 62 mh_getopt (&argc, &argv, NULL, MH_GETOPT_DEFAULT_FOLDER,
92 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, 63 args_doc, prog_doc, NULL);
93 opt_handler, NULL, &index);
94 64
95 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); 65 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
96 66
97 mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur"); 67 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
98 68
99 status = mu_msgset_foreach_message (msgset, rmm, NULL); 69 status = mu_msgset_foreach_message (msgset, rmm, NULL);
100 70
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
26 #include <time.h> 26 #include <time.h>
27 #include <mailutils/observer.h> 27 #include <mailutils/observer.h>
28 28
29 static char progdoc[] = N_("GNU MH scan"); 29 static char prog_doc[] = N_("GNU MH scan");
30 static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); 30 static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
31 31
32 static int clear; 32 static int clear;
...@@ -107,7 +107,7 @@ main (int argc, char **argv) ...@@ -107,7 +107,7 @@ main (int argc, char **argv)
107 MU_APP_INIT_NLS (); 107 MU_APP_INIT_NLS ();
108 108
109 mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER, 109 mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
110 args_doc, progdoc, NULL); 110 args_doc, prog_doc, NULL);
111 111
112 if (mh_format_parse (format_str, &format)) 112 if (mh_format_parse (format_str, &format))
113 { 113 {
......
...@@ -23,91 +23,13 @@ ...@@ -23,91 +23,13 @@
23 #include <stdarg.h> 23 #include <stdarg.h>
24 #include <pwd.h> 24 #include <pwd.h>
25 25
26 static char doc[] = N_("GNU MH send")"\v" 26 static char prog_doc[] = N_("GNU MH send");
27 N_("Options marked with `*' are not yet implemented.\n\
28 Use -help to obtain the list of traditional MH options.");
29 static char args_doc[] = N_("FILE [FILE...]"); 27 static char args_doc[] = N_("FILE [FILE...]");
30 28
31 /* GNU options */
32 static struct argp_option options[] = {
33 {"alias", ARG_ALIAS, N_("FILE"), 0,
34 N_("specify additional alias file") },
35 {"draft", ARG_DRAFT, NULL, 0,
36 N_("use prepared draft") },
37 {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
38 N_("specify the folder for message drafts") },
39 {"draftmessage", ARG_DRAFTMESSAGE, N_("MSG"), 0,
40 N_("use MSG from the draftfolder as a draft") },
41 {"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0,
42 N_("undo the effect of the last --draftfolder option") },
43 {"filter", ARG_FILTER, N_("FILE"), 0,
44 N_("* use filter FILE to preprocess the body of the message") },
45 {"nofilter", ARG_NOFILTER, NULL, 0,
46 N_("* undo the effect of the last --filter option") },
47 {"format", ARG_FORMAT, N_("BOOL"), OPTION_ARG_OPTIONAL,
48 N_("* reformat To: and Cc: addresses") },
49 {"noformat", ARG_NOFORMAT, NULL, OPTION_HIDDEN, "" },
50 {"forward", ARG_FORWARD, N_("BOOL"), OPTION_ARG_OPTIONAL,
51 N_("* in case of failure forward the draft along with the failure notice to the sender") },
52 {"noforward", ARG_NOFORWARD, NULL, OPTION_HIDDEN, "" },
53 {"mime", ARG_MIME, N_("BOOL"), OPTION_ARG_OPTIONAL,
54 N_("* use MIME encapsulation") },
55 {"nomime", ARG_NOMIME, NULL, OPTION_HIDDEN, "" },
56 {"msgid", ARG_MSGID, N_("BOOL"), OPTION_ARG_OPTIONAL,
57 N_("add Message-ID: field") },
58 {"nomsgid", ARG_NOMSGID, NULL, OPTION_HIDDEN, ""},
59 {"push", ARG_PUSH, N_("BOOL"), OPTION_ARG_OPTIONAL,
60 N_("run in the background") },
61 {"nopush", ARG_NOPUSH, NULL, OPTION_HIDDEN, "" },
62 {"preserve", ARG_PRESERVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
63 N_("keep draft files") },
64 {"keep", 0, NULL, OPTION_ALIAS, NULL},
65 {"split", ARG_SPLIT, N_("SECONDS"), 0,
66 N_("split the draft into several partial messages and send them with SECONDS interval") },
67 {"chunksize", ARG_CHUNKSIZE, N_("NUMBER"), 0,
68 N_("set the size of chunk for --split (in bytes)") },
69 {"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
70 N_("print the transcript of interactions with the transport system") },
71 {"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "" },
72 {"watch", ARG_WATCH, N_("BOOL"), OPTION_ARG_OPTIONAL,
73 N_("monitor the delivery of mail") },
74 {"nowatch", ARG_NOWATCH, NULL, OPTION_HIDDEN, "" },
75 {"width", ARG_WIDTH, N_("NUMBER"), 0,
76 N_("* make header fields no longer than NUMBER columns") },
77 { 0 }
78 };
79
80 /* Traditional MH options */
81 struct mh_option mh_option[] = {
82 { "alias", MH_OPT_ARG, "aliasfile" },
83 { "draft" },
84 { "draftfolder", MH_OPT_ARG, "folder" },
85 { "draftmessage", MH_OPT_ARG, "message" },
86 { "nodraftfolder" },
87 { "filter", MH_OPT_ARG, "filterfile" },
88 { "nofilter" },
89 { "format", MH_OPT_BOOL },
90 { "forward", MH_OPT_BOOL },
91 { "mime", MH_OPT_BOOL },
92 { "msgid", MH_OPT_BOOL },
93 { "push", MH_OPT_BOOL },
94 { "preserve", MH_OPT_BOOL },
95 { "keep", MH_OPT_BOOL },
96 { "split", MH_OPT_ARG, "seconds" },
97 { "verbose", MH_OPT_BOOL },
98 { "watch", MH_OPT_BOOL },
99 { "width" },
100 { NULL }
101 };
102
103 static const char *draftfolder; /* Use this draft folder */ 29 static const char *draftfolder; /* Use this draft folder */
104 static int use_draftfolder = 1; 30 static int use_draftfolder = 1;
105 static int use_draft; 31 static int use_draft;
106 32
107 static int reformat_recipients; /* --format option */
108 static int forward_notice; /* Forward the failure notice to the sender,
109 --forward flag */
110 static int mime_encaps; /* Use MIME encapsulation */
111 static int append_msgid; /* Append Message-ID: header */ 33 static int append_msgid; /* Append Message-ID: header */
112 static int background; /* Operate in the background */ 34 static int background; /* Operate in the background */
113 35
...@@ -117,7 +39,6 @@ static unsigned long split_interval; /* Interval in seconds between sending two ...@@ -117,7 +39,6 @@ static unsigned long split_interval; /* Interval in seconds between sending two
117 static size_t split_size = 76*632; /* Size of split parts */ 39 static size_t split_size = 76*632; /* Size of split parts */
118 static int verbose; /* Produce verbose diagnostics */ 40 static int verbose; /* Produce verbose diagnostics */
119 static int watch; /* Watch the delivery process */ 41 static int watch; /* Watch the delivery process */
120 static unsigned width = 76; /* Maximum width of header fields */
121 42
122 static int keep_files; /* Keep draft files */ 43 static int keep_files; /* Keep draft files */
123 44
...@@ -128,147 +49,116 @@ static int keep_files; /* Keep draft files */ ...@@ -128,147 +49,116 @@ static int keep_files; /* Keep draft files */
128 watch_printf c;\ 49 watch_printf c;\
129 } while (0) 50 } while (0)
130 51
131 static int add_file (char *name); 52 static int add_file (char const *name);
132 static void mesg_list_fixup (void); 53 static void mesg_list_fixup (void);
133 54
134 static error_t 55 static void
135 opt_handler (int key, char *arg, struct argp_state *state) 56 add_alias (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
136 { 57 {
137 char *p;
138
139 switch (key)
140 {
141 case ARG_ALIAS:
142 mh_alias_read (arg, 1); 58 mh_alias_read (arg, 1);
143 break; 59 }
144
145 case ARG_CHUNKSIZE:
146 split_size = strtoul (arg, &p, 10);
147 if (*p)
148 {
149 argp_error (state, "%s: %s", arg, _("invalid number"));
150 exit (1);
151 }
152 break;
153
154 case ARG_DRAFT:
155 use_draft = 1;
156 break;
157 60
158 case ARG_DRAFTFOLDER: 61 static void
159 draftfolder = arg; 62 set_draftfolder (struct mu_parseopt *po, struct mu_option *opt,
63 char const *arg)
64 {
65 draftfolder = mu_strdup (arg);
160 use_draftfolder = 1; 66 use_draftfolder = 1;
161 break; 67 }
162
163 case ARG_NODRAFTFOLDER:
164 draftfolder = NULL;
165 use_draftfolder = 0;
166 break;
167 68
168 case ARG_DRAFTMESSAGE: 69 static void
70 add_draftmessage (struct mu_parseopt *po, struct mu_option *opt,
71 char const *arg)
72 {
169 add_file (arg); 73 add_file (arg);
170 break; 74 }
171
172 case ARG_FILTER:
173 mh_opt_notimpl ("-filter");
174 break;
175
176 case ARG_NOFILTER:
177 mh_opt_notimpl ("-nofilter");
178 break;
179
180 case ARG_FORMAT:
181 mh_opt_notimpl_warning ("-format");
182 reformat_recipients = is_true (arg);
183 break;
184
185 case ARG_NOFORMAT:
186 mh_opt_notimpl_warning ("-noformat");
187 reformat_recipients = 0;
188 break;
189
190 case ARG_FORWARD:
191 mh_opt_notimpl_warning ("-forward");
192 forward_notice = is_true (arg);
193 break;
194
195 case ARG_NOFORWARD:
196 mh_opt_notimpl_warning ("-noforward");
197 forward_notice = 0;
198 break;
199
200 case ARG_MIME:
201 mh_opt_notimpl_warning ("-mime");
202 mime_encaps = is_true (arg);
203 break;
204
205 case ARG_NOMIME:
206 mh_opt_notimpl_warning ("-nomime");
207 mime_encaps = 0;
208 break;
209
210 case ARG_MSGID:
211 append_msgid = is_true (arg);
212 break;
213
214 case ARG_NOMSGID:
215 append_msgid = 0;
216 break;
217
218 case ARG_PRESERVE:
219 keep_files = is_true (arg);
220 break;
221
222 case ARG_PUSH:
223 background = is_true (arg);
224 break;
225
226 case ARG_NOPUSH:
227 background = 0;
228 break;
229
230 case ARG_SPLIT:
231 split_message = 1;
232 split_interval = strtoul (arg, &p, 10);
233 if (*p)
234 {
235 argp_error (state, "%s: %s", arg, _("invalid number"));
236 exit (1);
237 }
238 break;
239
240 case ARG_VERBOSE:
241 verbose = is_true (arg);
242 break;
243
244 case ARG_NOVERBOSE:
245 verbose = 0;
246 break;
247
248 case ARG_WATCH:
249 watch = is_true (arg);
250 break;
251
252 case ARG_NOWATCH:
253 watch = 0;
254 break;
255 75
256 case ARG_WIDTH: 76 static void
257 mh_opt_notimpl_warning ("-width"); 77 set_split_opt (struct mu_parseopt *po, struct mu_option *opt,
258 width = strtoul (arg, &p, 10); 78 char const *arg)
259 if (*p) 79 {
80 char *errmsg;
81 int rc = mu_str_to_c (arg, opt->opt_type, opt->opt_ptr, &errmsg);
82 if (rc)
260 { 83 {
261 argp_error (state, _("invalid number")); 84 char const *errtext;
262 exit (1); 85 if (errmsg)
263 } 86 errtext = errmsg;
264 break; 87 else
88 errtext = mu_strerror (rc);
265 89
266 default: 90 mu_parseopt_error (po, "%s%s: %s", po->po_long_opt_start,
267 return ARGP_ERR_UNKNOWN; 91 opt->opt_long, errtext);
92 free (errmsg);
93
94 if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT))
95 exit (po->po_exit_error);
268 } 96 }
269 return 0; 97 split_message = 1;
270 } 98 }
271 99
100 static struct mu_option options[] = {
101 { "alias", 0, N_("FILE"), MU_OPTION_DEFAULT,
102 N_("specify additional alias file"),
103 mu_c_string, NULL, add_alias },
104 { "draft", 0, NULL, MU_OPTION_DEFAULT,
105 N_("use prepared draft"),
106 mu_c_bool, &use_draft },
107 { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
108 N_("specify the folder for message drafts"),
109 mu_c_string, NULL, set_draftfolder },
110 { "draftmessage", 0, N_("MSG"), MU_OPTION_DEFAULT,
111 N_("use MSG from the draftfolder as a draft"),
112 mu_c_string, NULL, add_draftmessage },
113 { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
114 N_("undo the effect of the last --draftfolder option"),
115 mu_c_int, &use_draftfolder, NULL, "1" },
116 { "filter", 0, N_("FILE"), MU_OPTION_HIDDEN,
117 N_("use filter FILE to preprocess the body of the message"),
118 mu_c_string, NULL, mh_opt_notimpl },
119 { "nofilter", 0, NULL, MU_OPTION_HIDDEN,
120 N_("undo the effect of the last --filter option"),
121 mu_c_string, NULL, mh_opt_notimpl },
122 { "format", 0, NULL, MU_OPTION_HIDDEN,
123 N_("reformat To: and Cc: addresses"),
124 mu_c_string, NULL, mh_opt_notimpl_warning },
125 { "noformat", 0, NULL, MU_OPTION_HIDDEN },
126 { "forward", 0, NULL, MU_OPTION_HIDDEN,
127 N_("in case of failure forward the draft along with the failure notice to the sender"),
128 mu_c_string, NULL, mh_opt_notimpl_warning },
129 { "noforward", 0, NULL, MU_OPTION_HIDDEN, "" },
130 { "mime", 0, NULL, MU_OPTION_HIDDEN,
131 N_("use MIME encapsulation"),
132 mu_c_bool, NULL, mh_opt_notimpl_warning },
133 { "msgid", 0, NULL, MU_OPTION_DEFAULT,
134 N_("add Message-ID: field"),
135 mu_c_bool, &append_msgid },
136 { "push", 0, NULL, MU_OPTION_DEFAULT,
137 N_("run in the background"),
138 mu_c_bool, &background },
139 { "preserve", 0, NULL, MU_OPTION_DEFAULT,
140 N_("keep draft files"),
141 mu_c_bool, &keep_files },
142 { "keep", 0, NULL, MU_OPTION_ALIAS },
143 { "split", 0, N_("SECONDS"), MU_OPTION_DEFAULT,
144 N_("split the draft into several partial messages and send them with SECONDS interval"),
145 mu_c_ulong, &split_interval, set_split_opt },
146 { "chunksize", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
147 N_("set the size of chunk for --split (in bytes)"),
148 mu_c_size, &split_size },
149 { "verbose", 0, NULL, MU_OPTION_DEFAULT,
150 N_("print the transcript of interactions with the transport system"),
151 mu_c_bool, &verbose },
152 { "watch", 0, NULL, MU_OPTION_DEFAULT,
153 N_("monitor the delivery of mail"),
154 mu_c_bool, &watch },
155 { "width", 0, N_("NUMBER"), MU_OPTION_HIDDEN,
156 N_("make header fields no longer than NUMBER columns"),
157 mu_c_string, NULL, mh_opt_notimpl_warning },
158
159 MU_OPTION_END
160 };
161
272 static void 162 static void
273 watch_printf (const char *fmt, ...) 163 watch_printf (const char *fmt, ...)
274 { 164 {
...@@ -291,7 +181,7 @@ static mu_list_t mesg_list; ...@@ -291,7 +181,7 @@ static mu_list_t mesg_list;
291 static mu_property_t mts_profile; 181 static mu_property_t mts_profile;
292 182
293 int 183 int
294 add_file (char *name) 184 add_file (char const *name)
295 { 185 {
296 struct list_elt *elt; 186 struct list_elt *elt;
297 187
...@@ -859,17 +749,12 @@ int ...@@ -859,17 +749,12 @@ int
859 main (int argc, char **argv) 749 main (int argc, char **argv)
860 { 750 {
861 mu_mailbox_t mbox = NULL; 751 mu_mailbox_t mbox = NULL;
862 int index;
863 char *p; 752 char *p;
864 int rc; 753 int rc;
865 754
866 MU_APP_INIT_NLS (); 755 MU_APP_INIT_NLS ();
867 756
868 mh_argp_init (); 757 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
869 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
870 opt_handler, NULL, &index);
871 argc -= index;
872 argv += index;
873 758
874 mh_read_aliases (); 759 mh_read_aliases ();
875 /* Process the mtstailor file */ 760 /* Process the mtstailor file */
......
...@@ -19,55 +19,9 @@ ...@@ -19,55 +19,9 @@
19 19
20 #include <mh.h> 20 #include <mh.h>
21 21
22 static char doc[] = N_("GNU MH show")"\v" 22 static char prog_doc[] = N_("GNU MH show");
23 N_("Use -help to obtain the list of traditional MH options.");
24 static char args_doc[] = N_("[+FOLDER] [MSGLIST]"); 23 static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
25 24
26 #define ARG_PASS ARG_MAX
27
28 static struct argp_option options[] = {
29 {"draft", ARG_DRAFT, NULL, 0,
30 N_("show the draft file") },
31 {"file", ARG_FILE, N_("FILE"), 0,
32 N_("show this file") },
33 {"header", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL,
34 N_("display a description of the message before the message itself") },
35 {"noheader", ARG_HEADER, NULL, OPTION_HIDDEN, "" },
36 {"showproc", ARG_SHOWPROC, N_("PROGRAM"), 0,
37 N_("use PROGRAM to show messages")},
38 {"noshowproc", ARG_NOSHOWPROC, NULL, 0,
39 N_("disable the use of the \"showproc:\" profile component") },
40
41 {"form", ARG_FORM, N_("FILE"), 0,
42 N_("read format from given file")},
43 {"moreproc", ARG_MOREPROC, N_("PROG"), 0,
44 N_("use this PROG as pager"), },
45 {"nomoreproc", ARG_NOMOREPROC, NULL, 0,
46 N_("disable the use of moreproc") },
47 {"length", ARG_LENGTH, N_("NUMBER"), 0,
48 N_("set output screen length")},
49 {"width", ARG_WIDTH, N_("NUMBER"), 0,
50 N_("set output width")},
51
52 {NULL}
53 };
54
55 /* Traditional MH options */
56 struct mh_option mh_option[] = {
57 { "draft" },
58 { "file", MH_OPT_ARG, "file" },
59 { "header", MH_OPT_BOOL },
60 { "showproc", MH_OPT_ARG, "program" },
61 { "noshowproc" },
62 { "form", MH_OPT_ARG, "formatfile"},
63 { "width", MH_OPT_ARG, "number"},
64 { "length", MH_OPT_ARG, "number"},
65 { "moreproc", MH_OPT_ARG, "program"},
66 { "nomoreproc" },
67
68 { NULL }
69 };
70
71 int use_draft; 25 int use_draft;
72 int use_showproc = 1; 26 int use_showproc = 1;
73 int header_option = 1; 27 int header_option = 1;
...@@ -101,70 +55,74 @@ insarg (char *arg) ...@@ -101,70 +55,74 @@ insarg (char *arg)
101 } 55 }
102 } 56 }
103 57
104 static const char * 58 static void
105 findopt (int key) 59 set_draft (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
106 {
107 struct argp_option *p;
108
109 for (p = options; p->name; p++)
110 if (p->key == key)
111 return p->name;
112 abort ();
113 }
114
115 static error_t
116 opt_handler (int key, char *arg, struct argp_state *state)
117 { 60 {
118 switch (key)
119 {
120 case ARG_FOLDER:
121 mh_set_current_folder (arg);
122 break;
123
124 case ARG_DRAFT:
125 if (use_draft || file) 61 if (use_draft || file)
126 argp_error (state, _("only one file at a time!")); 62 {
63 mu_parseopt_error (po, _("only one file at a time!"));
64 exit (po->po_exit_error);
65 }
127 use_draft = 1; 66 use_draft = 1;
128 break; 67 }
129 68
130 case ARG_FILE: 69 static void
70 set_file (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
71 {
131 if (use_draft || file) 72 if (use_draft || file)
132 argp_error (state, _("only one file at a time!")); 73 {
74 mu_parseopt_error (po, _("only one file at a time!"));
75 exit (po->po_exit_error);
76 }
133 file = mh_expand_name (NULL, arg, NAME_FILE); 77 file = mh_expand_name (NULL, arg, NAME_FILE);
134 break; 78 }
135 79
136 case ARG_HEADER: 80 static void
137 header_option = is_true (arg); 81 add_show_arg (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
138 break; 82 {
139 83 char *name = mu_alloc (strlen (opt->opt_long) + 2);
140 case ARG_NOHEADER: 84 name[0] = '-';
141 header_option = 0; 85 strcpy (name + 1, opt->opt_long);
142 break; 86 addarg (name);
143
144 case ARG_SHOWPROC:
145 showproc = arg;
146 break;
147
148 case ARG_NOSHOWPROC:
149 use_showproc = 0;
150 break;
151
152 case ARG_NOMOREPROC:
153 case ARG_FORM:
154 case ARG_MOREPROC:
155 case ARG_LENGTH:
156 case ARG_WIDTH:
157 addarg (findopt (key));
158 if (arg) 87 if (arg)
159 addarg (arg); 88 addarg (arg);
160 break;
161
162 default:
163 return ARGP_ERR_UNKNOWN;
164 }
165 return 0;
166 } 89 }
167 90
91 static struct mu_option options[] = {
92 { "draft", 0, NULL, MU_OPTION_DEFAULT,
93 N_("show the draft file"),
94 mu_c_string, NULL, set_draft },
95 { "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
96 N_("show this file"),
97 mu_c_string, NULL, set_file },
98 { "header", 0, NULL, MU_OPTION_DEFAULT,
99 N_("display a description of the message before the message itself"),
100 mu_c_bool, &header_option },
101 { "showproc", 0, N_("PROGRAM"), MU_OPTION_DEFAULT,
102 N_("use PROGRAM to show messages"),
103 mu_c_string, &showproc },
104 { "noshowproc", 0, NULL, MU_OPTION_DEFAULT,
105 N_("disable the use of the \"showproc:\" profile component"),
106 mu_c_int, &use_showproc, NULL, "0" },
107 { "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
108 N_("read format from given file"),
109 mu_c_string, NULL, add_show_arg },
110 { "moreproc", 0, N_("PROG"), MU_OPTION_DEFAULT,
111 N_("use this PROG as pager"),
112 mu_c_string, NULL, add_show_arg },
113 { "nomoreproc", 0, NULL, MU_OPTION_DEFAULT,
114 N_("disable the use of moreproc"),
115 mu_c_string, NULL, add_show_arg },
116 { "length", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
117 N_("set output screen length"),
118 mu_c_string, NULL, add_show_arg },
119 { "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
120 N_("set output width"),
121 mu_c_string, NULL, add_show_arg },
122
123 MU_OPTION_END
124 };
125
168 static int 126 static int
169 resolve_mime (size_t num, mu_message_t msg, void *data) 127 resolve_mime (size_t num, mu_message_t msg, void *data)
170 { 128 {
...@@ -222,7 +180,6 @@ checkfile (char *file) ...@@ -222,7 +180,6 @@ checkfile (char *file)
222 int 180 int
223 main (int argc, char **argv) 181 main (int argc, char **argv)
224 { 182 {
225 int index = 0;
226 mu_mailbox_t mbox; 183 mu_mailbox_t mbox;
227 mu_msgset_t msgset; 184 mu_msgset_t msgset;
228 const char *p; 185 const char *p;
...@@ -234,13 +191,11 @@ main (int argc, char **argv) ...@@ -234,13 +191,11 @@ main (int argc, char **argv)
234 showargc = 1; 191 showargc = 1;
235 showargv = mu_calloc (showargmax, sizeof showargv[0]); 192 showargv = mu_calloc (showargmax, sizeof showargv[0]);
236 193
237 mh_argp_init (); 194 mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
238 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, 195 args_doc, prog_doc, NULL);
239 opt_handler, NULL, &index); 196
240 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
241 197
242 argc -= index; 198 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
243 argv += index;
244 199
245 if (use_draft || file) 200 if (use_draft || file)
246 { 201 {
......
...@@ -22,72 +22,10 @@ ...@@ -22,72 +22,10 @@
22 #include <unistd.h> 22 #include <unistd.h>
23 #include <signal.h> 23 #include <signal.h>
24 24
25 static char doc[] = N_("GNU MH sortm")"\v" 25 static char prog_doc[] = N_("GNU MH sortm")"\v"
26 N_("Use -help to obtain the list of traditional MH options."); 26 N_("Use -help to obtain the list of traditional MH options.");
27 static char args_doc[] = N_("[MSGLIST]"); 27 static char args_doc[] = N_("[MSGLIST]");
28 28
29 #define ARG_QUICKSORT 1024
30 #define ARG_SHELL 1025
31
32 /* GNU options */
33 static struct argp_option options[] = {
34 {"folder", ARG_FOLDER, N_("FOLDER"), 0,
35 N_("specify folder to operate upon")},
36
37 {N_("Setting sort keys:"), 0, NULL, OPTION_DOC, NULL, 0},
38 {"datefield", ARG_DATEFIELD, N_("STRING"), 0,
39 N_("sort on the date field (default `Date:')"), 10},
40 {"nodatefield", ARG_NODATEFIELD, NULL, 0,
41 N_("undo the effect of the last --datefield option"), 10},
42 {"limit", ARG_LIMIT, N_("DAYS"), 0,
43 N_("consider two datefields equal if their difference lies within the given nuber of DAYS."), 11},
44 {"nolimit", ARG_NOLIMIT, NULL, 0,
45 N_("undo the effect of the last --limit option"), 11},
46 {"textfield", ARG_TEXTFIELD, N_("STRING"), 0,
47 N_("sort on the text field"), 15},
48 {"notextfield", ARG_NOTEXTFIELD, NULL, 0,
49 N_("undo the effect of the last --textfield option"), 15},
50 {"numfield", ARG_NUMFIELD, N_("STRING"), 0,
51 N_("sort on the numeric field"), 16},
52
53 {N_("Actions:"), 0, NULL, OPTION_DOC, NULL, 16},
54 {"reorder", ARG_REORDER, 0, 0,
55 N_("reorder the messages (default)"), 20 },
56 {"dry-run", ARG_DRY_RUN, 0, 0,
57 N_("do not do anything, only show what would have been done"), 20 },
58 {"list", ARG_LIST, 0, 0,
59 N_("list the sorted messages"), 20 },
60 {"form", ARG_FORM, N_("FILE"), 0,
61 N_("read format from given file"), 23},
62 {"format", ARG_FORMAT, N_("FORMAT"), 0,
63 N_("use this format string"), 23},
64
65 {"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
66 N_("verbosely list executed actions"), 30 },
67 {"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "" },
68
69 {N_("Select sort algorithm:"), 0, NULL, OPTION_DOC, NULL, 30},
70
71 {"shell", ARG_SHELL, 0, 0,
72 N_("use shell algorithm"), 40 },
73 {"quicksort", ARG_QUICKSORT, 0, 0,
74 N_("use quicksort algorithm (default)"), 40 },
75
76 { NULL },
77 };
78
79 /* Traditional MH options */
80 struct mh_option mh_option[] = {
81 { "datefield", MH_OPT_ARG, "field" },
82 { "nodatefield" },
83 { "textfield", MH_OPT_ARG, "field" },
84 { "notextfield" },
85 { "limit", MH_OPT_ARG, "days" },
86 { "nolimit" },
87 { "verbose", MH_OPT_BOOL },
88 { NULL },
89 };
90
91 static int limit; 29 static int limit;
92 static int verbose; 30 static int verbose;
93 static mu_mailbox_t mbox; 31 static mu_mailbox_t mbox;
...@@ -98,115 +36,175 @@ static size_t msgcount; ...@@ -98,115 +36,175 @@ static size_t msgcount;
98 36
99 static size_t current_num; 37 static size_t current_num;
100 38
101 #define ACTION_REORDER 0 39 enum
102 #define ACTION_DRY_RUN 1 40 {
103 #define ACTION_LIST 2 41 ACTION_REORDER,
42 ACTION_DRY_RUN,
43 ACTION_LIST
44 };
104 45
105 static int algorithm = ARG_QUICKSORT; 46 enum
47 {
48 algo_quicksort,
49 algo_shell
50 };
51 static int algorithm = algo_quicksort;
106 static int action = ACTION_REORDER; 52 static int action = ACTION_REORDER;
107 static char *format_str = mh_list_format; 53 static char *format_str = mh_list_format;
108 static mh_format_t format; 54 static mh_format_t format;
109 55
110 typedef int (*compfun) (void *, void *); 56 typedef int (*compfun) (void *, void *);
111 static void addop (char *field, compfun comp); 57 static void addop (char const *field, compfun comp);
112 static void remop (compfun comp); 58 static void remop (compfun comp);
113 static int comp_text (void *a, void *b); 59 static int comp_text (void *a, void *b);
114 static int comp_date (void *a, void *b); 60 static int comp_date (void *a, void *b);
115 static int comp_number (void *a, void *b); 61 static int comp_number (void *a, void *b);
116 62
117 static error_t 63 static void
118 opt_handler (int key, char *arg, struct argp_state *state) 64 add_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
119 { 65 {
120 switch (key)
121 {
122 case ARG_FOLDER:
123 mh_set_current_folder (arg);
124 break;
125
126 case ARG_DATEFIELD:
127 addop (arg, comp_date); 66 addop (arg, comp_date);
128 break; 67 }
129 68
130 case ARG_NUMFIELD: 69 static void
70 add_numfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
71 {
131 addop (arg, comp_number); 72 addop (arg, comp_number);
132 break; 73 }
133
134 case ARG_NODATEFIELD:
135 remop (comp_date);
136 break;
137 74
138 case ARG_TEXTFIELD: 75 static void
76 add_textfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
77 {
139 addop (arg, comp_text); 78 addop (arg, comp_text);
140 break; 79 }
141
142 case ARG_NOTEXTFIELD:
143 remop (comp_text);
144 break;
145
146 case ARG_LIMIT:
147 limit = strtoul (arg, NULL, 0);
148 break;
149
150 case ARG_NOLIMIT:
151 limit = -1;
152 break;
153
154 case ARG_VERBOSE:
155 if (!arg || mu_isalpha (arg[0]))
156 verbose = is_true (arg);
157 else
158 verbose = arg[0] - '0';
159 break;
160 80
161 case ARG_NOVERBOSE: 81 static void
162 verbose = 0; 82 rem_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
163 break; 83 {
84 remop (comp_date);
85 }
164 86
165 case ARG_FORM: 87 static void
166 mh_read_formfile (arg, &format_str); 88 rem_numfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
167 break; 89 {
90 remop (comp_number);
91 }
168 92
169 case ARG_FORMAT: 93 static void
170 format_str = arg; 94 rem_textfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
171 break; 95 {
96 remop (comp_text);
97 }
172 98
173 case ARG_REORDER: 99 static void
100 set_action_reorder (struct mu_parseopt *po, struct mu_option *opt,
101 char const *arg)
102 {
174 action = ACTION_REORDER; 103 action = ACTION_REORDER;
175 break; 104 }
176 105
177 case ARG_LIST: 106 static void
107 set_action_list (struct mu_parseopt *po, struct mu_option *opt,
108 char const *arg)
109 {
178 action = ACTION_LIST; 110 action = ACTION_LIST;
179 break; 111 }
180 112
181 case ARG_DRY_RUN: 113 static void
114 set_action_dry_run (struct mu_parseopt *po, struct mu_option *opt,
115 char const *arg)
116 {
182 action = ACTION_DRY_RUN; 117 action = ACTION_DRY_RUN;
183 if (!verbose) 118 if (!verbose)
184 verbose = 1; 119 verbose = 1;
185 break; 120 }
186 121
187 case ARG_SHELL: 122 static void
188 case ARG_QUICKSORT: 123 set_algo_shell (struct mu_parseopt *po, struct mu_option *opt,
189 algorithm = key; 124 char const *arg)
190 break; 125 {
126 algorithm = algo_shell;
127 }
191 128
192 default: 129 static void
193 return ARGP_ERR_UNKNOWN; 130 set_algo_quicksort (struct mu_parseopt *po, struct mu_option *opt,
194 } 131 char const *arg)
195 return 0; 132 {
133 algorithm = algo_quicksort;
196 } 134 }
197 135
136 static struct mu_option options[] = {
137 MU_OPTION_GROUP (N_("Setting sort keys:")),
138 { "datefield", 0, N_("STRING"), MU_OPTION_DEFAULT,
139 N_("sort on the date field (default `Date:')"),
140 mu_c_string, NULL, add_datefield },
141 { "nodatefield", 0, NULL, MU_OPTION_DEFAULT,
142 N_("don't sort on the date field"),
143 mu_c_string, NULL, rem_datefield },
144 { "limit", 0, N_("DAYS"), MU_OPTION_DEFAULT,
145 N_("consider two datefields equal if their difference lies within the given nuber of DAYS."),
146 mu_c_int, &limit },
147 { "nolimit", 0, NULL, MU_OPTION_DEFAULT,
148 N_("undo the effect of the last -limit option"),
149 mu_c_int, &limit, NULL, "-1" },
150 { "textfield", 0, N_("STRING"), MU_OPTION_DEFAULT,
151 N_("sort on the text field"),
152 mu_c_string, NULL, add_textfield },
153 { "notextfield", 0, NULL, MU_OPTION_DEFAULT,
154 N_("don't sort on the text field"),
155 mu_c_string, NULL, rem_textfield },
156 { "numfield", 0, N_("STRING"), MU_OPTION_DEFAULT,
157 N_("sort on the numeric field"),
158 mu_c_string, NULL, add_numfield },
159 { "nonumfield", 0, NULL, MU_OPTION_DEFAULT,
160 N_("don't sort on the numeric field"),
161 mu_c_string, NULL, rem_numfield },
162
163 MU_OPTION_GROUP (N_("Actions:")),
164 { "reorder", 0, NULL, MU_OPTION_DEFAULT,
165 N_("reorder the messages (default)"),
166 mu_c_string, NULL, set_action_reorder },
167 { "dry-run", 0, NULL, MU_OPTION_DEFAULT,
168 N_("do not do anything, only show what would have been done"),
169 mu_c_string, NULL, set_action_dry_run },
170 { "list", 0, NULL, MU_OPTION_DEFAULT,
171 N_("list the sorted messages"),
172 mu_c_string, NULL, set_action_list },
173
174 { "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
175 N_("read format from given file"),
176 mu_c_string, &format_str, mh_opt_read_formfile },
177 { "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT,
178 N_("use this format string"),
179 mu_c_string, &format_str },
180
181 { "verbose", 0, NULL, MU_OPTION_DEFAULT,
182 N_("verbosely list executed actions"),
183 mu_c_bool, &verbose },
184
185 MU_OPTION_GROUP (N_("Select sort algorithm:")),
186 { "shell", 0, NULL, MU_OPTION_DEFAULT,
187 N_("use shell algorithm"),
188 mu_c_string, NULL, set_algo_shell },
189
190 { "quicksort", 0, NULL, MU_OPTION_DEFAULT,
191 N_("use quicksort algorithm (default)"),
192 mu_c_string, NULL, set_algo_quicksort },
193
194 MU_OPTION_END
195 };
198 196
199 /* *********************** Comparison functions **************************** */ 197 /* *********************** Comparison functions **************************** */
200 struct comp_op 198 struct comp_op
201 { 199 {
202 char *field; 200 char const *field;
203 compfun comp; 201 compfun comp;
204 }; 202 };
205 203
206 static mu_list_t oplist; 204 static mu_list_t oplist;
207 205
208 static void 206 static void
209 addop (char *field, compfun comp) 207 addop (char const *field, compfun comp)
210 { 208 {
211 struct comp_op *op = mu_alloc (sizeof (*op)); 209 struct comp_op *op = mu_alloc (sizeof (*op));
212 210
...@@ -497,11 +495,11 @@ sort () ...@@ -497,11 +495,11 @@ sort ()
497 495
498 switch (algorithm) 496 switch (algorithm)
499 { 497 {
500 case ARG_QUICKSORT: 498 case algo_quicksort:
501 qsort (msgarr, msgcount, sizeof (msgarr[0]), comp); 499 qsort (msgarr, msgcount, sizeof (msgarr[0]), comp);
502 break; 500 break;
503 501
504 case ARG_SHELL: 502 case algo_shell:
505 shell_sort (); 503 shell_sort ();
506 break; 504 break;
507 } 505 }
...@@ -599,19 +597,17 @@ fill_msgarr (mu_msgset_t msgset) ...@@ -599,19 +597,17 @@ fill_msgarr (mu_msgset_t msgset)
599 } 597 }
600 598
601 599
602 /* Main */
603
604 int 600 int
605 main (int argc, char **argv) 601 main (int argc, char **argv)
606 { 602 {
607 int index;
608 mu_url_t url; 603 mu_url_t url;
609 mu_msgset_t msgset; 604 mu_msgset_t msgset;
610 605
611 MU_APP_INIT_NLS (); 606 MU_APP_INIT_NLS ();
612 mh_argp_init (); 607
613 mh_argp_parse (&argc, &argv, 0, options, mh_option, 608 mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
614 args_doc, doc, opt_handler, NULL, &index); 609 args_doc, prog_doc, NULL);
610
615 if (!oplist) 611 if (!oplist)
616 addop ("date", comp_date); 612 addop ("date", comp_date);
617 613
...@@ -627,9 +623,6 @@ main (int argc, char **argv) ...@@ -627,9 +623,6 @@ main (int argc, char **argv)
627 if (memcmp (mbox_path, "mh:", 3) == 0) 623 if (memcmp (mbox_path, "mh:", 3) == 0)
628 mbox_path += 3; 624 mbox_path += 3;
629 625
630 argc -= index;
631 argv += index;
632
633 mh_mailbox_get_cur (mbox, &current_num); 626 mh_mailbox_get_cur (mbox, &current_num);
634 627
635 mh_msgset_parse (&msgset, mbox, argc, argv, "all"); 628 mh_msgset_parse (&msgset, mbox, argc, argv, "all");
......
...@@ -53,11 +53,11 @@ Mail/inbox/5 ...@@ -53,11 +53,11 @@ Mail/inbox/5
53 Mail/inbox/6 53 Mail/inbox/6
54 ]) 54 ])
55 55
56 MH_CHECK([refile --copy],[refile02 refile--copy],[ 56 MH_CHECK([refile -copy],[refile02 refile-copy],[
57 MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) 57 MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
58 MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty,[Mail/teaparty]) 58 MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty,[Mail/teaparty])
59 echo 'Current-Folder: teaparty' > Mail/context 59 echo 'Current-Folder: teaparty' > Mail/context
60 refile --copy 3 4 +inbox || exit $? 60 refile -copy 3 4 +inbox || exit $?
61 find Mail/inbox -name '[[0-9]]' | sort 61 find Mail/inbox -name '[[0-9]]' | sort
62 cmp Mail/inbox/6 Mail/teaparty/3 >/dev/null || echo "Message 3 differs" 62 cmp Mail/inbox/6 Mail/teaparty/3 >/dev/null || echo "Message 3 differs"
63 cmp Mail/inbox/7 Mail/teaparty/4 >/dev/null || echo "Message 4 differs" 63 cmp Mail/inbox/7 Mail/teaparty/4 >/dev/null || echo "Message 4 differs"
......
...@@ -19,88 +19,45 @@ ...@@ -19,88 +19,45 @@
19 19
20 #include <mh.h> 20 #include <mh.h>
21 21
22 static char doc[] = "GNU MH whatnow"; 22 static char prog_doc[] = "GNU MH whatnow";
23 static char args_doc[] = N_("[FILE]"); 23 static char args_doc[] = N_("[FILE]");
24 24
25 /* GNU options */
26 static struct argp_option options[] = {
27 {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
28 N_("specify the folder for message drafts")},
29 {"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0,
30 N_("undo the effect of the last --draftfolder option")},
31 {"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0,
32 N_("invoke the draftmessage facility")},
33 {"editor", ARG_EDITOR, N_("PROG"), 0, N_("set the editor program to use")},
34 {"noedit", ARG_NOEDIT, 0, 0, N_("suppress the initial edit")},
35 {"prompt", ARG_PROMPT, N_("STRING"), 0, N_("set the prompt")},
36
37 { NULL }
38 };
39
40 /* Traditional MH options */
41 struct mh_option mh_option[] = {
42 { "draftfolder", MH_OPT_ARG, "folder" },
43 { "nodraftfolder" },
44 { "draftmessage" },
45 { "editor", MH_OPT_ARG, "program" },
46 { "noedit" },
47 { "prompt" },
48 { NULL }
49 };
50
51 struct mh_whatnow_env wh_env = { 0 }; 25 struct mh_whatnow_env wh_env = { 0 };
52 static int initial_edit = 1; 26 static int initial_edit = 1;
53 static char *draftmessage = "cur"; 27 static char *draftmessage = "cur";
54 static const char *draftfolder = NULL; 28 static const char *draftfolder = NULL;
55 29
56 static error_t 30 static struct mu_option options[] = {
57 opt_handler (int key, char *arg, struct argp_state *state) 31 { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
58 { 32 N_("specify the folder for message drafts"),
59 switch (key) 33 mu_c_string, &draftfolder },
60 { 34 { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
61 case ARG_DRAFTFOLDER: 35 N_("undo the effect of the last -draftfolder option"),
62 draftfolder = arg; 36 mu_c_string, &draftfolder, mh_opt_clear_string },
63 break; 37 { "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT,
64 38 N_("invoke the draftmessage facility"),
65 case ARG_EDITOR: 39 mu_c_string, &draftmessage },
66 wh_env.editor = arg; 40 { "editor", 0, N_("PROG"), MU_OPTION_DEFAULT,
67 break; 41 N_("set the editor program to use"),
68 42 mu_c_string, &wh_env.editor },
69 case ARG_NODRAFTFOLDER: 43 { "noedit", 0, NULL, MU_OPTION_DEFAULT,
70 draftfolder = NULL; 44 N_("suppress the initial edit"),
71 break; 45 mu_c_int, &initial_edit, NULL, "0" },
72 46 { "prompt", 0, N_("STRING"), MU_OPTION_DEFAULT,
73 case ARG_NOEDIT: 47 N_("set the prompt"),
74 initial_edit = 0; 48 mu_c_string, &wh_env.prompt },
75 break; 49 MU_OPTION_END
76 50 };
77 case ARG_DRAFTMESSAGE:
78 draftmessage = arg;
79 break;
80
81 case ARG_PROMPT:
82 wh_env.prompt = arg;
83 break;
84
85 default:
86 return ARGP_ERR_UNKNOWN;
87 }
88 return 0;
89 }
90 51
91 int 52 int
92 main (int argc, char **argv) 53 main (int argc, char **argv)
93 { 54 {
94 int index;
95
96 MU_APP_INIT_NLS (); 55 MU_APP_INIT_NLS ();
97 56
98 mh_argp_init ();
99 mh_whatnow_env_from_environ (&wh_env); 57 mh_whatnow_env_from_environ (&wh_env);
100 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, 58
101 opt_handler, NULL, &index); 59 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
102 argc -= index; 60
103 argv += index;
104 if (argc) 61 if (argc)
105 wh_env.draftfile = argv[0]; 62 wh_env.draftfile = argv[0];
106 else if (draftfolder) 63 else if (draftfolder)
......
...@@ -17,99 +17,58 @@ ...@@ -17,99 +17,58 @@
17 17
18 #include <mh.h> 18 #include <mh.h>
19 19
20 static char doc[] = N_("GNU MH whom")"\v" 20 static char prog_doc[] = N_("GNU MH whom");
21 N_("Use -help to obtain the list of traditional MH options.");
22 static char args_doc[] = "[FILE]"; 21 static char args_doc[] = "[FILE]";
23 22
24 /* GNU options */
25 static struct argp_option options[] = {
26 {"alias", ARG_ALIAS, N_("FILE"), 0,
27 N_("specify additional alias file") },
28 {"draft", ARG_DRAFT, NULL, 0,
29 N_("use prepared draft") },
30 {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
31 N_("specify the folder for message drafts") },
32 {"draftmessage", ARG_DRAFTMESSAGE, NULL, 0,
33 N_("treat the arguments as a list of messages from the draftfolder") },
34 {"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0,
35 N_("undo the effect of the last --draftfolder option") },
36 {"check", ARG_CHECK, N_("BOOL"), OPTION_ARG_OPTIONAL,
37 N_("check if addresses are deliverable") },
38 {"nocheck", ARG_NOCHECK, NULL, OPTION_HIDDEN, "" },
39
40 {NULL}
41 };
42
43 /* Traditional MH options */
44 struct mh_option mh_option[] = {
45 { "alias", MH_OPT_ARG, "aliasfile" },
46 { "draft" },
47 { "draftfolder", MH_OPT_ARG, "folder" },
48 { "draftmessage", MH_OPT_ARG, "message" },
49 { "nodraftfolder" },
50 { "check", MH_OPT_BOOL },
51 {NULL}
52 };
53
54 static int check_recipients; 23 static int check_recipients;
55 static int use_draft; /* Use the prepared draft */ 24 static int use_draft; /* Use the prepared draft */
56 static const char *draft_folder; /* Use this draft folder */ 25 static const char *draft_folder; /* Use this draft folder */
57 26
58 static error_t 27 static void
59 opt_handler (int key, char *arg, struct argp_state *state) 28 add_alias (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
60 { 29 {
61 switch (key)
62 {
63 case ARG_ALIAS:
64 mh_alias_read (arg, 1); 30 mh_alias_read (arg, 1);
65 break; 31 }
66
67 case ARG_DRAFT:
68 use_draft = 1;
69 break;
70
71 case ARG_DRAFTFOLDER:
72 draft_folder = arg;
73 break;
74
75 case ARG_NODRAFTFOLDER:
76 draft_folder = NULL;
77 break;
78 32
79 case ARG_DRAFTMESSAGE: 33 static void
34 set_draftmessage (struct mu_parseopt *po, struct mu_option *opt,
35 char const *arg)
36 {
80 if (!draft_folder) 37 if (!draft_folder)
81 draft_folder = mh_global_profile_get ("Draft-Folder", 38 draft_folder = mh_global_profile_get ("Draft-Folder",
82 mu_folder_directory ()); 39 mu_folder_directory ());
83 break;
84
85 case ARG_CHECK:
86 check_recipients = is_true (arg);
87 break;
88
89 case ARG_NOCHECK:
90 check_recipients = 0;
91 break;
92
93 default:
94 return ARGP_ERR_UNKNOWN;
95 }
96 return 0;
97 } 40 }
98 41
42 static struct mu_option options[] = {
43 { "alias", 0, N_("FILE"), MU_OPTION_DEFAULT,
44 N_("specify additional alias file"),
45 mu_c_string, NULL, add_alias },
46 { "draft", 0, NULL, MU_OPTION_DEFAULT,
47 N_("use prepared draft"),
48 mu_c_bool, &use_draft },
49 { "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
50 N_("specify the folder for message drafts"),
51 mu_c_string, &draft_folder },
52 { "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
53 N_("undo the effect of the last -draftfolder option"),
54 mu_c_string, &draft_folder, mh_opt_clear_string },
55 { "draftmessage", 0, NULL, MU_OPTION_DEFAULT,
56 N_("treat the arguments as a list of messages from the draftfolder"),
57 mu_c_string, NULL, set_draftmessage },
58 { "check", 0, NULL, MU_OPTION_DEFAULT,
59 N_("check if addresses are deliverable"),
60 mu_c_bool, &check_recipients },
61 MU_OPTION_END
62 };
63
99 int 64 int
100 main (int argc, char **argv) 65 main (int argc, char **argv)
101 { 66 {
102 int index;
103 char *name = "draft"; 67 char *name = "draft";
104 68
105 MU_APP_INIT_NLS (); 69 MU_APP_INIT_NLS ();
106 70
107 mh_argp_init (); 71 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
108 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
109 opt_handler, NULL, &index);
110
111 argc -= index;
112 argv += index;
113 72
114 if (!use_draft && argc > 0) 73 if (!use_draft && argc > 0)
115 name = argv[0]; 74 name = argv[0];
......
...@@ -144,7 +144,6 @@ mh/inc.c ...@@ -144,7 +144,6 @@ mh/inc.c
144 mh/install-mh.c 144 mh/install-mh.c
145 mh/mark.c 145 mh/mark.c
146 mh/mboxprop.c 146 mh/mboxprop.c
147 mh/mh_argp.c
148 mh/mh_fmtgram.y 147 mh/mh_fmtgram.y
149 mh/mh_format.c 148 mh/mh_format.c
150 mh/mh_getopt.c 149 mh/mh_getopt.c
......