From 966a860c0eef32bfe8cab5c5c05c54a8e115270b Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Wed, 3 Nov 2010 12:27:17 +0200 Subject: Improve command module system in mu. Add a `help' command. * mu/Makefile.am (MODULES): New variable. Put all commands there. (mu_SOURCES): Include $(MODULES). (EXTRA_DIST): Add mu-setup.h mu-setup.c mu-setup.awk (BUILT_SOURCES): New variable. (mu-setup.h, mu-setup.c): New goals. * mu/mu.c (doc): Remove command description: it is generated automatically. (mu_help_filter): New function. (argp): Use mu_help_filter. (mutool_action_tab): Remove. (mutool_nosys,find_action): Remove. (mu_help): New function. (main): Use dispatch_find_action. * mu/mu.h: Include mailutils/types.h (mutool_pop, mutool_filter, mutool_flt2047) (mutool_info, mutool_query, mutool_acl) (mutool_wicket, mutool_ldflags, mutool_cflags): Remove protos. (mu_help, dispatch_find_action, dispatch_docstring): New protos. * mu/acl.c: Add MU Setup comment. * mu/cflags.c: Likewise. * mu/filter.c: Likewise. * mu/flt2047.c: Likewise. * mu/info.c: Likewise. * mu/ldflags.c: Likewise. * mu/pop.c: Likewise. * mu/query.c: Likewise. * mu/wicket.c: Likewise. * mu/mu-setup.awk: New file. * mu/help.c: New file. * mu/dispatch.c: New file. * mu/.gitignore: Add mu-status.[ch] * po/POTFILES.in: Add mu/dispatch.c and mu/help.c. --- mu/.gitignore | 2 ++ mu/Makefile.am | 24 +++++++++++---- mu/acl.c | 8 +++++ mu/cflags.c | 7 +++++ mu/dispatch.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ mu/filter.c | 10 ++++++- mu/flt2047.c | 8 +++++ mu/help.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ mu/info.c | 8 +++++ mu/ldflags.c | 7 +++++ mu/mu-setup.awk | 64 ++++++++++++++++++++++++++++++++++++++++ mu/mu.c | 90 +++++++++++++++++++-------------------------------------- mu/mu.h | 17 ++++------- mu/pop.c | 8 +++++ mu/query.c | 8 +++++ mu/shell.c | 1 + mu/wicket.c | 9 ++++++ po/POTFILES.in | 2 ++ 18 files changed, 347 insertions(+), 78 deletions(-) create mode 100644 mu/dispatch.c create mode 100644 mu/help.c create mode 100644 mu/mu-setup.awk diff --git a/mu/.gitignore b/mu/.gitignore index 92cfbd63a..c159d488d 100644 --- a/mu/.gitignore +++ b/mu/.gitignore @@ -1 +1,3 @@ mu +mu-setup.c +mu-setup.h diff --git a/mu/Makefile.am b/mu/Makefile.am index 6fe40d907..52ab78c7e 100644 --- a/mu/Makefile.am +++ b/mu/Makefile.am @@ -22,22 +22,28 @@ if MU_COND_SUPPORT_POP POP_C=pop.c endif -EXTRA_DIST=pop.c +EXTRA_DIST=pop.c mu-setup.h mu-setup.c mu-setup.awk +BUILT_SOURCES=mu-setup.h mu-setup.c -mu_SOURCES = \ +MODULES = \ acl.c\ cflags.c\ - info.c\ - mu.h\ - mu.c\ filter.c\ flt2047.c\ + help.c\ + info.c\ ldflags.c\ $(POP_C)\ query.c\ - shell.c\ wicket.c +mu_SOURCES = \ + dispatch.c\ + mu.h\ + mu.c\ + shell.c\ + $(MODULES) + mu_LDADD = \ ${MU_APP_LIBRARIES}\ ${MU_LIB_MBOX}\ @@ -61,3 +67,9 @@ AM_CPPFLAGS = \ -DGUILE_LIBS="\"$(GUILE_LIBS)\"" \ -DPYTHON_LIBS="\"$(PYTHON_LIBS)\"" \ -DI18NLIBS="\"$(LIBINTL)\"" + +mu-setup.h: Makefile.am $(MODULES) + $(AM_V_GEN)$(AWK) -f $(top_srcdir)/mu/mu-setup.awk -v mode=h $(MODULES) > mu-setup.h + +mu-setup.c: Makefile.am $(MODULES) + $(AM_V_GEN)$(AWK) -f $(top_srcdir)/mu/mu-setup.awk -v mode=c $(MODULES) > mu-setup.c diff --git a/mu/acl.c b/mu/acl.c index 0c9cc217b..9d8646066 100644 --- a/mu/acl.c +++ b/mu/acl.c @@ -30,6 +30,7 @@ #include "xalloc.h" static char acl_doc[] = N_("mu acl - test access control lists."); +char acl_docstring[] = N_("test access control lists"); static char acl_args_doc[] = N_("ADDRESS [ADDRESS...]"); static struct argp_option acl_options[] = { @@ -191,3 +192,10 @@ mutool_acl (int argc, char **argv) return 0; } + +/* + MU Setup: acl + mu-handler: mutool_acl + mu-docstring: acl_docstring + End MU Setup: +*/ diff --git a/mu/cflags.c b/mu/cflags.c index 9d177d065..ea510dad5 100644 --- a/mu/cflags.c +++ b/mu/cflags.c @@ -23,6 +23,7 @@ #include static char cflags_doc[] = N_("mu cflags - show compiler options"); +char cflags_docstring[] = N_("show compiler options"); static struct argp cflags_argp = { NULL, @@ -43,4 +44,10 @@ mutool_cflags (int argc, char **argv) return 0; } +/* + MU Setup: cflags + mu-handler: mutool_cflags + mu-docstring: cflags_docstring + End MU Setup: +*/ diff --git a/mu/dispatch.c b/mu/dispatch.c new file mode 100644 index 000000000..0769b7f2b --- /dev/null +++ b/mu/dispatch.c @@ -0,0 +1,78 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + GNU Mailutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Mailutils is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Mailutils. If not, see . */ + +#if defined(HAVE_CONFIG_H) +# include +#endif +#include +#include +#include +#include +#include "mu.h" +#include "mu-setup.h" +#include "xalloc.h" + +struct mutool_action_tab +{ + const char *name; + mutool_action_t action; + const char *docstring; +}; + +struct mutool_action_tab mutool_action_tab[] = { +#include "mu-setup.c" + { NULL } +}; + +mutool_action_t +dispatch_find_action (const char *name) +{ + struct mutool_action_tab *p; + + for (p = mutool_action_tab; p->name; p++) + if (strcmp (p->name, name) == 0) + return p->action; + return NULL; +} + +char * +dispatch_docstring (const char *text) +{ + mu_stream_t str; + struct mutool_action_tab *p; + mu_off_t size; + size_t n; + char *ret; + + mu_memory_stream_create (&str, MU_STREAM_RDWR); + mu_stream_printf (str, "%s\n%s\n\n", text, _("Commands are:")); + for (p = mutool_action_tab; p->name; p++) + mu_stream_printf (str, " mu %-16s - %s\n", + p->name, gettext (p->docstring)); + mu_stream_printf (str, "\n%s\n\n", + _("Try `mu COMMAND --help' to get help on a particular " + "COMMAND.")); + mu_stream_printf (str, "%s\n", _("Options are:")); + mu_stream_flush (str); + mu_stream_size (str, &size); + ret = xmalloc (size + 1); + mu_stream_seek (str, 0, MU_SEEK_SET, NULL); + mu_stream_read (str, ret, size, &n); + ret[n] = 0; + mu_stream_destroy (&str); + return ret; +} + diff --git a/mu/filter.c b/mu/filter.c index dedc2f910..2facaeef7 100644 --- a/mu/filter.c +++ b/mu/filter.c @@ -23,7 +23,8 @@ #include "argp.h" #include "mu.h" -static char filter_doc[] = N_("mu filter"); +static char filter_doc[] = N_("mu filter - apply a filter to the input"); +char filter_docstring[] = N_("apply a filter to the input"); static char filter_args_doc[] = N_("NAME"); static struct argp_option filter_options[] = { @@ -157,3 +158,10 @@ mutool_filter (int argc, char **argv) return 0; } + +/* + MU Setup: filter + mu-handler: mutool_filter + mu-docstring: filter_docstring + End MU Setup: +*/ diff --git a/mu/flt2047.c b/mu/flt2047.c index 7c6c9d62b..ecd7e2711 100644 --- a/mu/flt2047.c +++ b/mu/flt2047.c @@ -24,6 +24,7 @@ #include "mu.h" static char flt2047_doc[] = N_("mu 2047 - decode/encode message headers."); +char flt2047_docstring[] = N_("decode/encode email message headers"); static char flt2047_args_doc[] = N_("[text]"); static struct argp_option flt2047_options[] = { @@ -153,3 +154,10 @@ mutool_flt2047 (int argc, char **argv) return 0; } + +/* + MU Setup: 2047 + mu-handler: mutool_flt2047 + mu-docstring: flt2047_docstring + End MU Setup: +*/ diff --git a/mu/help.c b/mu/help.c new file mode 100644 index 000000000..c389765cd --- /dev/null +++ b/mu/help.c @@ -0,0 +1,74 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + GNU Mailutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Mailutils is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Mailutils. If not, see . */ + +/* mu help - specjalnie dla Wojtka :) */ + +#if defined(HAVE_CONFIG_H) +# include +#endif +#include +#include +#include "mailutils/libargp.h" +#include "mu.h" + +static char help_doc[] = N_("mu help - display a terse help summary"); +char help_docstring[] = N_("display a terse help summary"); +static char help_args_doc[] = N_("[COMMAND]"); + +static struct argp help_argp = { + NULL, + NULL, + help_args_doc, + help_doc, + NULL, + NULL, + NULL +}; + +int +mutool_help (int argc, char **argv) +{ + int index; + + if (argp_parse (&help_argp, argc, argv, ARGP_IN_ORDER, &index, NULL)) + return 1; + + if (index == argc - 1) + { + mutool_action_t action = dispatch_find_action (argv[index]); + if (!action) + { + mu_error (_("don't know what %s is"), argv[index]); + exit (1); + } + argv[0] = argv[index]; + argv[1] = "--help"; + return action (2, argv); + } + else if (argc != index) + { + mu_error (_("too many arguments")); + exit (1); + } + return mu_help (); +} + +/* + MU Setup: help + mu-handler: mutool_help + mu-docstring: help_docstring + End MU Setup: +*/ diff --git a/mu/info.c b/mu/info.c index e101d2b14..48f903cdd 100644 --- a/mu/info.c +++ b/mu/info.c @@ -26,6 +26,7 @@ static char info_doc[] = N_("mu info - print a list of configuration\ options used to build mailutils; optional arguments are interpreted\ as a list of configuration options to check for."); +char info_docstring[] = N_("show Mailutils configuration"); static char info_args_doc[] = N_("[capa...]"); static struct argp_option info_options[] = { @@ -91,3 +92,10 @@ mutool_info (int argc, char **argv) } return 0; } + +/* + MU Setup: info + mu-handler: mutool_info + mu-docstring: info_docstring + End MU Setup: +*/ diff --git a/mu/ldflags.c b/mu/ldflags.c index 59ac5ebae..f93536c6f 100644 --- a/mu/ldflags.c +++ b/mu/ldflags.c @@ -23,6 +23,7 @@ #include static char ldflags_doc[] = N_("mu ldflags - list libraries required to link"); +char ldflags_docstring[] = N_("list libraries required to link"); static char ldflags_args_doc[] = N_("KEYWORD [KEYWORD...]"); static struct argp ldflags_argp = { @@ -191,3 +192,9 @@ mutool_ldflags (int argc, char **argv) return 0; } +/* + MU Setup: ldflags + mu-handler: mutool_ldflags + mu-docstring: ldflags_docstring + End MU Setup: +*/ diff --git a/mu/mu-setup.awk b/mu/mu-setup.awk new file mode 100644 index 000000000..5d261f1d9 --- /dev/null +++ b/mu/mu-setup.awk @@ -0,0 +1,64 @@ +# This file is part of GNU Mailutils. +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GNU Mailutils is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2, or (at +# your option) any later version. +# +# GNU Mailutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Mailutils. If not, see . + +state == 0 && /MU Setup:/ { + if (NF != 3) { + print FILENAME ":" NR ":", "missing module name" > "/dev/stderr" + exit(1) + } else { + state = 1; + module_name=$3; + if (modules[module_name]) { + print FILENAME ":" NR ":", "this module already declared" > "/dev/stderr" + print modules[module_name] ":", "location of the prior declaration" > "/dev/stderr" + } else + modules[module_name] = (FILENAME":"NR); + } +} +state == 1 && /mu-.*:/ { + setup[module_name,substr($1,4,length($1)-4)] = $2; + next +} +state == 1 && /End MU Setup/ { state = 0 } +END { + print "/* -*- buffer-read-only: t -*- vi: set ro:" + print " THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT." + print "*/" + + vartab[1] = "handler" + vartab[2] = "docstring" + n = asorti(modules,modname) + for (i = 1; i <= n; i++) { + name = modname[i] + for (j in vartab) { + if (!setup[name,vartab[j]]) { + print modules[name] ":", "mu-" vartab[j], "not defined" + err = 1 + } + } + if (err) + continue + if (mode == "h") { + print "extern int", setup[name,"handler"], "(int argc, char **argv);" + print "extern char " setup[name,"docstring"] "[];" + } else { + print "{", "\"" name "\",", setup[name,"handler"] ",", setup[name,"docstring"], "}," + } + } +} + + + diff --git a/mu/mu.c b/mu/mu.c index 8649efe6c..b5e8bc690 100644 --- a/mu/mu.c +++ b/mu/mu.c @@ -25,25 +25,7 @@ #include "mu.h" static char args_doc[] = N_("COMMAND [CMDOPTS]"); -static char doc[] = N_("mu -- GNU Mailutils multi-purpose tool.\n\ -Commands are:\n\ - mu info - show Mailutils configuration\n\ - mu query - query configuration values\n\ - mu pop - POP3 client program\n\ - mu filter - filter program\n\ - mu 2047 - decode/encode message headers as per RFC 2047\n\ - mu acl - test access control lists\n\ - mu wicket - find matching URL in wicket\n\ - mu ldflags- list libraries required to link\n\ - mu cflags - list compiler flags\n\ -\n\ -Try `mu COMMAND --help' to get help on a particular COMMAND.\n\ -\n\ -Options are:\n"); -/* FIXME: add - mu imap - mu send [opts] - */ +static char doc[] = N_("mu -- GNU Mailutils multi-purpose tool."); static struct argp_option options[] = { { NULL } @@ -60,13 +42,31 @@ parse_opt (int key, char *arg, struct argp_state *state) return 0; } +static char * +mu_help_filter (int key, const char *text, void *input) +{ + char *s; + + switch (key) + { + case ARGP_KEY_HELP_PRE_DOC: + s = dispatch_docstring (text); + break; + + default: + s = (char*) text; + } + return s; +} + + static struct argp argp = { options, parse_opt, args_doc, doc, NULL, - NULL, + mu_help_filter, NULL }; @@ -83,46 +83,16 @@ struct mu_cfg_param mu_tool_param[] = { { NULL } }; -struct mutool_action_tab -{ - const char *name; - mutool_action_t action; -}; - -static int -mutool_nosys (int argc, char **argv) -{ - mu_error (_("%s is not available because required code is not compiled"), - argv[0]); - return 1; -} - -struct mutool_action_tab mutool_action_tab[] = { - { "info", mutool_info }, -#ifdef ENABLE_POP - { "pop", mutool_pop }, -#else - { "pop", mutool_nosys }, -#endif - { "filter", mutool_filter }, - { "2047", mutool_flt2047 }, - { "query", mutool_query }, - { "acl", mutool_acl }, - { "wicket", mutool_wicket }, - { "ldflags", mutool_ldflags }, - { "cflags", mutool_cflags }, - { NULL } -}; - -static mutool_action_t -find_action (const char *name) +int +mu_help () { - struct mutool_action_tab *p; - - for (p = mutool_action_tab; p->name; p++) - if (strcmp (p->name, name) == 0) - return p->action; - return NULL; + char *x_argv[3]; + + x_argv[0] = (char*) mu_program_name; + x_argv[1] = "--help"; + x_argv[2] = NULL; + return mu_app_init (&argp, mu_tool_capa, mu_tool_param, + 2, x_argv, 0, NULL, NULL); } int @@ -155,7 +125,7 @@ main (int argc, char **argv) exit (1); } - action = find_action (argv[0]); + action = dispatch_find_action (argv[0]); if (!action) { mu_error (_("don't know what %s is"), argv[0]); diff --git a/mu/mu.h b/mu/mu.h index 4280b0ec0..d46bc41ce 100644 --- a/mu/mu.h +++ b/mu/mu.h @@ -14,6 +14,8 @@ You should have received a copy of the GNU General Public License along with GNU Mailutils. If not, see . */ +#include + typedef int (*mutool_action_t) (int argc, char **argv); struct mutool_command @@ -28,20 +30,13 @@ struct mutool_command const char *docstring;/* Documentation for this function. */ }; - -int mutool_pop (int argc, char **argv); -int mutool_filter (int argc, char **argv); -int mutool_flt2047 (int argc, char **argv); -int mutool_info (int argc, char **argv); -int mutool_query (int argc, char **argv); -int mutool_acl (int argc, char **argv); -int mutool_wicket (int argc, char **argv); -int mutool_ldflags (int argc, char **argv); -int mutool_cflags (int argc, char **argv); - extern char *mutool_shell_prompt; extern char **mutool_prompt_env; extern int mutool_shell_interactive; extern mu_stream_t mustrin, mustrout; int mutool_shell (const char *name, struct mutool_command *cmd); mu_stream_t mutool_open_pager (void); + +int mu_help (void); +mutool_action_t dispatch_find_action (const char *name); +char *dispatch_docstring (const char *text); diff --git a/mu/pop.c b/mu/pop.c index 311bd6775..bf2c93876 100644 --- a/mu/pop.c +++ b/mu/pop.c @@ -28,6 +28,7 @@ #include "xalloc.h" static char pop_doc[] = N_("mu pop - POP3 client shell."); +char pop_docstring[] = N_("POP3 client shell"); static char pop_args_doc[] = ""; static struct argp_option pop_options[] = { @@ -807,3 +808,10 @@ mutool_pop (int argc, char **argv) mutool_shell ("pop", pop_comtab); return 0; } + +/* + MU Setup: pop + mu-handler: mutool_pop + mu-docstring: pop_docstring + End MU Setup: +*/ diff --git a/mu/query.c b/mu/query.c index fd951c28e..6a1c55729 100644 --- a/mu/query.c +++ b/mu/query.c @@ -25,6 +25,7 @@ #include "mu.h" static char query_doc[] = N_("mu query - query configuration values."); +char query_docstring[] = N_("query configuration values"); static char query_args_doc[] = N_("path [path...]"); char *file_name; @@ -118,4 +119,11 @@ mutool_query (int argc, char **argv) return 0; } + +/* + MU Setup: query + mu-handler: mutool_query + mu-docstring: query_docstring + End MU Setup: +*/ diff --git a/mu/shell.c b/mu/shell.c index 51ed25afe..ab12fd46a 100644 --- a/mu/shell.c +++ b/mu/shell.c @@ -620,3 +620,4 @@ mutool_shell (const char *name, struct mutool_command *cmd) mu_stream_destroy (&mustrout); return 0; } + diff --git a/mu/wicket.c b/mu/wicket.c index 2ea8eec99..6cd971541 100644 --- a/mu/wicket.c +++ b/mu/wicket.c @@ -23,6 +23,7 @@ #include static char wicket_doc[] = N_("mu wicket - find matching URL in wicket"); +char wicket_docstring[] = N_("scan wickets for matching URLs"); static char wicket_args_doc[] = N_("NAME"); static struct argp_option wicket_options[] = { @@ -172,3 +173,11 @@ mutool_wicket (int argc, char **argv) mu_stream_destroy (&stream); return exit_code; } + + +/* + MU Setup: wicket + mu-handler: mutool_wicket + mu-docstring: wicket_docstring + End MU Setup: +*/ diff --git a/po/POTFILES.in b/po/POTFILES.in index b2d2a5bd8..8d2e5e6b5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -212,8 +212,10 @@ sieve/sieve.c sql/mysql.c mu/acl.c +mu/dispatch.c mu/filter.c mu/flt2047.c +mu/help.c mu/info.c mu/mu.c mu/pop.c -- cgit v1.2.1