diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-10 15:03:43 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-10 17:21:54 +0300 |
commit | 8b04169265fb9762b2c1dfca3f43068f5b8233be (patch) | |
tree | 43049c1809b2b70b21ed9300ebdd286d18833c8b | |
parent | bb242e454d5cf8b0c6bb1ca5d009ec18e86c0c2b (diff) | |
download | wydawca-8b04169265fb9762b2c1dfca3f43068f5b8233be.tar.gz wydawca-8b04169265fb9762b2c1dfca3f43068f5b8233be.tar.bz2 |
Update grecs.
* Makefile.am (ChangeLog): Use git2chg.awk.
* bootstrap.conf (gnulib_modules): Don't access grecs/gnulib.modules.
* configure.ac (GRECS_SETUP): Add options.
* gnulib.modules (getopt,gitlog-to-changelog)
(hash,error,version-etc): Remove.
* src/Makefile.am: Remove getopt.m4, use one from grecs.
* src/getopt.m4: Remove.
* src/cmdline.opt: Rewrite.
* src/config.c: Update.
* src/wydawca.h (spool) <aliases>: Change data type.
(all_spool_aliases): Change data type.
(config_finish): New proto.
* src/wydawca.c: Use grecs functions.
* src/dictionary.c: Likewise.
* src/net.c: Likewise.
* src/process.c: Likewise.
* src/mail.c: Use grecs_symtab.
* src/timer.c: Likewise.
* src/triplet.c: Likewise.
-rw-r--r-- | Makefile.am | 18 | ||||
-rw-r--r-- | bootstrap.conf | 2 | ||||
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | doc/wydawca.texi | 2 | ||||
-rw-r--r-- | gnulib.modules | 5 | ||||
m--------- | grecs | 0 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/cmdline.opt | 41 | ||||
-rw-r--r-- | src/config.c | 73 | ||||
-rw-r--r-- | src/dictionary.c | 4 | ||||
-rw-r--r-- | src/diskio.c | 2 | ||||
-rw-r--r-- | src/getopt.m4 | 517 | ||||
-rw-r--r-- | src/mail.c | 78 | ||||
-rw-r--r-- | src/net.c | 2 | ||||
-rw-r--r-- | src/process.c | 2 | ||||
-rw-r--r-- | src/timer.c | 79 | ||||
-rw-r--r-- | src/triplet.c | 84 | ||||
-rw-r--r-- | src/wydawca.c | 13 | ||||
-rw-r--r-- | src/wydawca.h | 10 |
19 files changed, 186 insertions, 759 deletions
diff --git a/Makefile.am b/Makefile.am index 95051ba..a182931 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,19 +22,11 @@ SUBDIRS=gnu grecs src doc etc tests distuninstallcheck_listfiles = \ find $(prefix) -type f -not -path '$(sysconfdir)/*' gen_start_date = 2009-01-25 .PHONY: ChangeLog -ChangeLog: - if test -d .git; then \ - $(top_srcdir)/build-aux/gitlog-to-changelog \ - --since=$(gen_start_date) | \ - sed '/<unknown>$$/d' | fmt -s > ChangeLog; \ - cat ChangeLog.svn | sed '/^Local Variables:/,/^End:/d' \ - >> ChangeLog; \ - echo "Local Variables:" >> ChangeLog; \ - echo "mode: change-log" >> ChangeLog; \ - echo "version-control: never" >> ChangeLog; \ - echo "buffer-read-only: t" >> ChangeLog; \ - echo "End:" >> ChangeLog; \ - fi +ChangeLog: + $(AM_V_GEN)if test -d .git; then \ + git log --pretty='format:%ct %an <%ae>%n%n%s%n%n%b%n' | \ + awk -f $(top_srcdir)/@GRECS_SUBDIR@/build-aux/git2chg.awk > ChangeLog; \ + fi diff --git a/bootstrap.conf b/bootstrap.conf index 6cdbbc4..8464d0d 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -29,13 +29,13 @@ git submodule update || exit $? avoided_gnulib_modules=' --avoid=lock --avoid=size_max ' # gnulib modules used by this package. -gnulib_modules="`grep -h '^[^#]' gnulib.modules grecs/gnulib.modules | sort | uniq`" +gnulib_modules="`grep -h '^[^#]' gnulib.modules | sort | uniq`" # Additional xgettext options to use. Use "\\\newline" to break lines. XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\ --flag=_:1:pass-c-format\\\ --flag=N_:1:pass-c-format\\\ --flag=error:3:c-format --flag=error_at_line:5:c-format\\\ diff --git a/configure.ac b/configure.ac index b72348b..0005006 100644 --- a/configure.ac +++ b/configure.ac @@ -12,18 +12,17 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with wydawca. If not, see <http://www.gnu.org/licenses/>. AC_PREREQ(2.63) -AC_INIT([wydawca], 2.1, [bug-wydawca@gnu.org.ua]) +AC_INIT([wydawca], 2.1.90, [bug-wydawca@gnu.org.ua]) AC_CONFIG_SRCDIR([src/wydawca.c]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADER([config.h]) -AM_INIT_AUTOMAKE([1.11 gnits tar-ustar dist-bzip2 dist-lzma dist-xz std-options -silent-rules]) +AM_INIT_AUTOMAKE([1.11 gnits tar-ustar dist-bzip2 dist-xz std-options silent-rules]) # Enable silent rules by default: AM_SILENT_RULES([yes]) # Checks for programs. AC_PROG_CC @@ -109,13 +108,13 @@ if test "$status_tcpwrap" = yes; then fi if test "$status_tcpwrap" = yes; then AC_DEFINE_UNQUOTED([WITH_LIBWRAP],1,[Defined if compiling with libwrap]) fi # Grecs subsystem -GRECS_SETUP +GRECS_SETUP([grecs],[git2chg getopt tests]) AH_BOTTOM([ #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) # define __attribute__(x) #endif @@ -134,12 +133,10 @@ if test -n "$GPG"; then AC_SUBST(WYDAWCA_GPGFILES, '$(GPGFILES)') fi AC_CONFIG_FILES([Makefile doc/Makefile gnu/Makefile - grecs/Makefile - grecs/src/Makefile src/Makefile etc/Makefile]) AC_OUTPUT diff --git a/doc/wydawca.texi b/doc/wydawca.texi index 7a2e3a7..961c2dc 100644 --- a/doc/wydawca.texi +++ b/doc/wydawca.texi @@ -3023,13 +3023,13 @@ This chapter presents a short reference of all @command{wydawca} command line options, in alphabetical order. @table @option @opsummary{config-file} @item --config-file=@var{file} @itemx -c @var{file} -Use @var{FILE} instead of the default configuration +Use @var{file} instead of the default configuration file. @xref{config-file, The @option{--config-file} option}. @opsummary{cron} @opsummary{syslog} diff --git a/gnulib.modules b/gnulib.modules index 3dbc445..f274913 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -1,20 +1,15 @@ xalloc c-ctype fnmatch obstack -getopt -gitlog-to-changelog -hash -error progname getline mkdtemp save-cwd backupfile strerror sysexits vasprintf inttostr strftime -version-etc xgethostname diff --git a/grecs b/grecs -Subproject edcc575bcdc9e50bdb79f422ad0f11dc79f3eaa +Subproject 8bd6f1e59b1663089bf8c81d8d2b14e20010c6e diff --git a/src/Makefile.am b/src/Makefile.am index a523a1a..b79e0ec 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,18 +45,18 @@ wydawca_SOURCES=\ vtab.c\ null.c\ timer.c\ report.c BUILT_SOURCES=cmdline.h -EXTRA_DIST=cmdline.opt getopt.m4 pp-setup update-2.0.awk +EXTRA_DIST=cmdline.opt pp-setup update-2.0.awk SUFFIXES=.opt .c .h .opt.h: - m4 -s $(srcdir)/getopt.m4 $< | sed '1d' > $@ + $(AM_V_GEN)m4 -s $(top_srcdir)/@GRECS_SUBDIR@/build-aux/getopt.m4 $< > $@ incdir=$(pkgdatadir)/$(VERSION)/include inc_DATA = $(PP_SETUP_FILE) LDADD=../grecs/src/libgrecs.a ../gnu/libgnu.a @SQLLIB@ @GPGMELIB@ @MAILUTILS_LIBS@ INCLUDES = -I$(top_srcdir)/grecs/src/ -I$(top_srcdir)/gnu -I../gnu @MAILUTILS_INCLUDES@ diff --git a/src/cmdline.opt b/src/cmdline.opt index 29eff3a..4c3d22f 100644 --- a/src/cmdline.opt +++ b/src/cmdline.opt @@ -1,7 +1,7 @@ -/* wydawca - automatic release submission daemon +/* wydawca - automatic release submission daemon -*- c -*- Copyright (C) 2007, 2009, 2010 Sergey Poznyakoff Wydawca 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 of the License, or (at your option) any later version. @@ -14,39 +14,42 @@ You should have received a copy of the GNU General Public License along with wydawca. If not, see <http://www.gnu.org/licenses/>. */ static struct obstack pp_cmd_stack; static int pp_cmd_stack_init; -static gl_list_t source_list; -static gl_list_t tag_list; +static struct grecs_list *source_list; +static struct grecs_list *tag_list; -static bool -string_eq (const void *elt1, const void *elt2) +static int +string_cmp (const void *elt1, const void *elt2) { - return strcmp ((const char *)elt1, (const char *)elt2) == 0; + return strcmp ((const char *)elt1, (const char *)elt2); } int selected_spools () { return (source_list != NULL || tag_list != NULL); } int enabled_spool_p (const struct spool *spool) { if (source_list || tag_list) - return (source_list && gl_list_search (source_list, spool->source_dir)) - || (tag_list && gl_list_search (tag_list, spool->tag)); + return (source_list && grecs_list_locate (source_list, spool->source_dir)) + || (tag_list && grecs_list_locate (tag_list, spool->tag)); return 1; } -OPTIONS_BEGIN(gnu, "wydawca", +OPTIONS_BEGIN("wydawca", [<wydawca synchronizes files from a set of upload directories with the corresponding distribution sites>], - [<UID [UID...]>]) + [<UID [UID...]>], + [<gnu>], + [<copyright_year=2011>], + [<copyright_holder=Sergey Poznyakoff>]) GROUP(Selecting program mode) OPTION(lint,t,, [<parse configuration file and exit>]) BEGIN @@ -101,26 +104,28 @@ BEGIN END OPTION(spool,S,TAG, [<process only spool with the given tag (may be used multiple times)>]) BEGIN if (!tag_list) - tag_list = gl_list_create_empty (&gl_linked_list_implementation, - string_eq, NULL, - NULL, false); - gl_list_add_last (tag_list, optarg); + { + tag_list = grecs_list_create (); + tag_list->cmp = string_cmp; + } + grecs_list_append (tag_list, optarg); END OPTION(source,s,SOURCE-DIR, [<process only spool with the given source (may be used multiple times)>]) BEGIN if (!source_list) - source_list = gl_list_create_empty (&gl_linked_list_implementation, - string_eq, NULL, - NULL, false); - gl_list_add_last (source_list, optarg); + { + source_list = grecs_list_create (); + source_list->cmp = string_cmp; + } + grecs_list_append (source_list, optarg); END GROUP(Logging) OPTION(syslog,,, [<log to syslog>]) diff --git a/src/config.c b/src/config.c index 9c75df6..7353f29 100644 --- a/src/config.c +++ b/src/config.c @@ -245,13 +245,13 @@ get_arg (grecs_locus_t *locus, grecs_value_t *value, unsigned n, int type) { if (n >= value->v.arg.c) { grecs_error (locus, 0, _("not enough arguments")); return NULL; } - value = value->v.arg.v + n; + value = value->v.arg.v[n]; if (value->type != type) { grecs_error (locus, 0, _("argument %d has wrong type"), n); return NULL; } return value; @@ -297,18 +297,17 @@ cb_email_address (enum grecs_callback_command cmd, return rc; } break; case GRECS_TYPE_LIST: { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (value->v.list); - - while (gl_list_iterator_next (&itr, &p, NULL)) + struct grecs_list_entry *ep; + + for (ep = value->v.list->head; ep; ep = ep->next) { - const grecs_value_t *vp = p; + const grecs_value_t *vp = ep->data; mu_address_t a; if (assert_string_arg (locus, cmd, vp)) return 1; rc = mu_address_create (&a, vp->v.string); if (rc == 0) @@ -497,30 +496,29 @@ parse_statmask (grecs_locus_t *loc, grecs_value_t *val, unsigned long *pmask) { int i; for (i = 0; i < val->v.arg.c; i++) { unsigned long x; - if (parse_single_statmask (loc, &val->v.arg.v[i], &x, &invert)) + if (parse_single_statmask (loc, val->v.arg.v[i], &x, &invert)) err = 1; else if (invert) mask &= ~x; else mask |= x; } } break; case GRECS_TYPE_LIST: { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (val->v.list); + struct grecs_list_entry *ep; - while (gl_list_iterator_next (&itr, &p, NULL)) + for (ep = val->v.list->head; ep; ep = ep->next) { - const grecs_value_t *vp = p; + const grecs_value_t *vp = ep->data; unsigned long x; if (parse_single_statmask (loc, vp, &x, &invert)) err = 1; else if (invert) mask &= ~x; @@ -683,26 +681,26 @@ cb_define_message (enum grecs_callback_command cmd, if (!value || value->type != GRECS_TYPE_ARRAY || value->v.arg.c != 2) { grecs_error (locus, 0, _("expected two arguments")); return 1; } - if (value->v.arg.v[0].type != GRECS_TYPE_STRING) + if (value->v.arg.v[0]->type != GRECS_TYPE_STRING) { grecs_error (locus, 0, _("first argument not a string")); return 1; } - ident = value->v.arg.v[0].v.string; + ident = value->v.arg.v[0]->v.string; - if (value->v.arg.v[1].type != GRECS_TYPE_STRING) + if (value->v.arg.v[1]->type != GRECS_TYPE_STRING) { grecs_error (locus, 0, _("second argument not a string")); return 1; } - register_message_template (ident, value->v.arg.v[1].v.string); + register_message_template (ident, value->v.arg.v[1]->v.string); return 0; } static struct grecs_keyword syslog_kw[] = { @@ -989,16 +987,16 @@ cb_dictionary_type (enum grecs_callback_command cmd, grecs_error (locus, 0, _("unknown dictionary type: %s"), value->v.string); return 0; } static int cb_dictionary_params (enum grecs_callback_command cmd, - grecs_locus_t *locus, - void *varptr, - grecs_value_t *value, - void *cb_data) + grecs_locus_t *locus, + void *varptr, + grecs_value_t *value, + void *cb_data) { struct dictionary *meth = varptr; size_t size; if (cmd != grecs_callback_set_value) { @@ -1008,37 +1006,35 @@ cb_dictionary_params (enum grecs_callback_command cmd, if (!value || value->type != GRECS_TYPE_LIST) { grecs_error (locus, 0, _("expected list value")); return 1; } - size = gl_list_size (value->v.list); + size = grecs_list_size (value->v.list); if (size == 0) { meth->parmc = 0; meth->parmv = NULL; } else { int i; - const void *p; - gl_list_iterator_t itr = gl_list_iterator (value->v.list); + struct grecs_list_entry *ep; meth->parmc = size; meth->parmv = xcalloc (size + 1, sizeof (meth->parmv[0])); - for (i = 0; gl_list_iterator_next (&itr, &p, NULL); i++) + for (i = 0, ep = value->v.list->head; ep; ep = ep->next, i++) { - const grecs_value_t *vp = p; + const grecs_value_t *vp = ep->data; if (assert_string_arg (locus, cmd, vp)) break; meth->parmv[i] = xstrdup (vp->v.string); } - gl_list_iterator_free (&itr); meth->parmv[i] = NULL; } return 0; } static struct grecs_keyword dictionary_kw[] = { @@ -1311,40 +1307,38 @@ cb_supp_groups (enum grecs_callback_command cmd, if (!value || value->type != GRECS_TYPE_LIST) { grecs_error (locus, 0, _("expected list value")); return 1; } - wydawca_supp_groupc = gl_list_size (value->v.list); + wydawca_supp_groupc = grecs_list_size (value->v.list); if (wydawca_supp_groupc == 0) wydawca_supp_groups = NULL; else { int i; - gl_list_iterator_t itr; - const void *p; + struct grecs_list_entry *ep; wydawca_supp_groups = xcalloc (wydawca_supp_groupc, sizeof (wydawca_supp_groups[0])); - itr = gl_list_iterator (value->v.list); - for (i = 0; gl_list_iterator_next (&itr, &p, NULL); i++) + + for (i = 0, ep = value->v.list->head; ep; ep = ep->next, i++) { - const grecs_value_t *vp = p; + const grecs_value_t *vp = ep->data; struct group *grp; if (assert_string_arg (locus, cmd, vp)) break; grp = getgrnam (vp->v.string); if (!grp) { grecs_error (locus, 0, _("no such group: %s"), value->v.string); break; } wydawca_supp_groups[i] = grp->gr_gid; } - gl_list_iterator_free (&itr); } return 0; } static struct grecs_keyword locking_kw[] = { @@ -1477,29 +1471,36 @@ static struct grecs_keyword wydawca_kw[] = { void config_help () { static char docstring[] = N_("Configuration file structure for wydawca.\n" "For more information, use `info wydawca configuration'."); - grecs_format_docstring (stdout, docstring, 0); - grecs_format_statement_array (stdout, wydawca_kw, 1, 0); + grecs_format_docstring (docstring, 0, stdout); + grecs_format_statement_array (wydawca_kw, 1, 0, stdout); } void config_init() { int i; struct servent *serv; - grecs_set_keywords (wydawca_kw); grecs_include_path_setup (DEFAULT_VERSION_INCLUDE_DIR, DEFAULT_INCLUDE_DIR, NULL); grecs_preprocessor = DEFAULT_PREPROCESSOR; - grecs_log_to_stderr = true; + grecs_log_to_stderr = 1; serv = getservbyname (PACKAGE, "tcp"); if (serv != NULL) grecs_default_port = serv->s_port; for (i = 0; i < dictionary_count; i++) default_dictionary[i] = dictionary_new (i, dictionary_builtin); } + +void +config_finish (struct grecs_node *tree) +{ + if (grecs_tree_process (tree, wydawca_kw)) + exit (EX_CONFIG); +} + diff --git a/src/dictionary.c b/src/dictionary.c index 7060cec..b7baf05 100644 --- a/src/dictionary.c +++ b/src/dictionary.c @@ -212,15 +212,15 @@ dictionary_quote_string (struct dictionary *dict, void *handle, return 0; } if (mp->quote) return mp->quote (dict, handle, input, poutput, psize); - size = wordsplit_quoted_length (input, 0, "e); + size = wordsplit_c_quoted_length (input, 0, "e); output = xmalloc (size + 1); - wordsplit_quote_copy (output, input, 0); + wordsplit_c_quote_copy (output, input, 0); output[size] = 0; *poutput = output; if (psize) *psize = size; return 0; diff --git a/src/diskio.c b/src/diskio.c index 46526d0..ed16e35 100644 --- a/src/diskio.c +++ b/src/diskio.c @@ -369,14 +369,12 @@ backup_file (const char *dst_file, const char *dst_dir, const char *file, for the argument description. */ int do_archive_file (const char *dst_file, const char *dst_dir, const char *file, const struct archive_descr *archive, const char *reldir) { - int rc = 0; - switch (archive->type) { case archive_none: break; case archive_directory: diff --git a/src/getopt.m4 b/src/getopt.m4 deleted file mode 100644 index fc50ff9..0000000 --- a/src/getopt.m4 +++ /dev/null @@ -1,517 +0,0 @@ -dnl This file is part of GNU Rush. -dnl Copyright (C) 2007, 2008, 2009, 2010 Sergey Poznyakoff. -dnl -dnl GNU Rush is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Rush is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Rush. If not, see <http://www.gnu.org/licenses/>. -divert(-1) -changequote([<,>]) -changecom(/*,*/) - -dnl upcase(ARGS...) -dnl Concatenate and convert ARGS to upper case. -dnl -define([<upcase>], [<translit([<$*>], [<a-z>], [<A-Z>])>]) - -dnl concat(ARGS...) -dnl Concatenate arguments, inserting ", " between each of pair of them. -dnl -define([<concat>],[<ifelse([<$#>],1,[<$1>],[<$1, concat(shift($@))>])>]) - -dnl flushleft(ARGS...) -dnl Concatenate ARGS and remove any leading whitespace -dnl -define([<flushleft>], - [<patsubst([<concat($*)>], [<^[ ]+>])>]) - -dnl chop(ARGS...) -dnl Concatenate ARGS and remove any trailing whitespace -dnl -define([<chop>], - [<patsubst([<$*>], [<[ ]+$>])>]) - -dnl escape(ARGS...) -dnl Concatenate ARGS and escape any occurrences of double-quotes with -dnl backslashes. -dnl -define([<escape>], -[<patsubst([<concat($*)>],[<[\"]>],[<\\\&>])>]) - -dnl prep(ARG) -dnl Prepare ARG for including in C strings: replace newlines with any amount -dnl of preceding and following whitespace by a single space character, remove -dnl leading whitespace, and escape double-quotes. -dnl -define([<prep>], - [<escape(flushleft(patsubst([<$1>],[<[ ]* -+[ ]*>],[< >])))>]) - -dnl SHORT_OPTS -dnl Accumulator for the 3rd argument of getopt_long -dnl -define([<SHORT_OPTS>],[<>]) - -dnl GROUP(STRING) -dnl Begin a named group of options -dnl -define([<GROUP>],[<dnl -divert(3) - { NULL, NULL, 0, N_("prep([<$1>])") }, -divert(-1)>]) - -define([<__GATHER_OPTIONS>],[< -define([<KEY>],ifelse([<$2>],,[<OPTION_>]upcase(patsubst($1,-,_)),'$2')) -ifelse([<$2>],,[< -divert(1) - KEY, -divert(-1) ->]) -define([<SELECTOR>],ifdef([<SELECTOR>],SELECTOR) case KEY:) -ifelse([<$1>],,,[< -divert(2) - { "$1", ARGTYPE, 0, KEY }, -divert(-1)>]) -dnl -define([<SHORT_OPTS>],SHORT_OPTS[<>]dnl -ifelse([<$2>],,,$2[<>]ifelse(ARGTYPE,[<no_argument>],,ARGTYPE,[<required_argument>],:,ARGTYPE,[<optional_argument>],::))) -dnl -ifelse([<$1>],,,dnl -[<define([<LONG_TAG>],ifelse(LONG_TAG,,[<--$1>],[<LONG_TAG; --$1>]))>]) -ifelse([<$2>],,,dnl -[<define([<SHORT_TAG>],ifelse(SHORT_TAG,,[<-$2>],[<SHORT_TAG; -$2>]))>]) ->]) - -dnl OPTION(long-opt, short-opt, [arg], [descr]) -dnl Introduce a command line option. Arguments: -dnl long-opt Long option. -dnl short-opt Short option (a single char) -dnl (At least one of long-opt or short-opt must be present) -dnl -dnl Optional arguments: -dnl arg Option argument. -dnl descr Option description -dnl -dnl If arg is absent, the option does not take any arguments. If arg is -dnl enclosed in square brackets, the option takes an optional argument. -dnl Otherwise, the argument is required. -dnl -dnl If descr is not given the option will not appear in the --help and -dnl --usage outputs. -dnl -define([<OPTION>],[< -pushdef([<LONG_TAG>]) -pushdef([<SHORT_TAG>]) -pushdef([<ARGNAME>],[<$3>]) -pushdef([<DOCSTRING>],[<prep([<$4>])>]) -pushdef([<ARGTYPE>],[<ifelse([<$3>],,[<no_argument>],dnl -patsubst([<$3>],[<\[.*\]>]),,[<optional_argument>],dnl -[<required_argument>])>]) -__GATHER_OPTIONS($@) ->]) - -dnl ALIAS(long-opt, short-opt) -dnl Declare aliases for the previous OPTION statement. -dnl long-opt Long option. -dnl short-opt Short option (a single char) -dnl (At least one of long-opt or short-opt must be present) -dnl An OPTION statement may be followed by any number of ALIAS statements. -dnl -define([<ALIAS>],[< -__GATHER_OPTIONS($1,$2) ->]) - -dnl BEGIN -dnl Start an action associated with the declared option. Must follow OPTION -dnl statement, with optional ALIAS statements in between. -dnl -define([<BEGIN>],[< -ifelse([<DOCSTRING>],,,[< -divert(3) - { "translit(dnl -ifelse(SHORT_TAG,,LONG_TAG,[<SHORT_TAG[<>]ifelse(LONG_TAG,,,; LONG_TAG)>]), - [<;>],[<,>])", ifelse(ARGNAME,,[<NULL, 0>], -[<ifelse(ARGTYPE,[<optional_argument>], -[<patsubst(ARGNAME,[<\[\(.*\)\]>],[<N_("\1"), 1>])>],[<N_("ARGNAME"), 0>])>]), N_("DOCSTRING") }, -divert(-1)>]) -popdef([<ARGTYPE>]) -popdef([<ARGNAME>]) -popdef([<DOCSTRING>]) -divert(4)dnl -popdef([<LONG_TAG>])dnl -popdef([<SHORT_TAG>])dnl - SELECTOR - { ->]) - -dnl END -dnl Finish the associated action -dnl -define([<END>],[< - break; - } -divert(-1) -undefine([<SELECTOR>])>]) - -dnl GETOPT(argc, argv, [default]) -dnl Emit option parsing code. Arguments: -dnl -dnl argc Name of the 1st argument to getopt_long. -dnl argv Name of the 2nd argument to getopt_long. -dnl default Code for the default branch -dnl -define([<GETOPT>],[< - { - int c; - -ifelse([<$#>],3,opterr = 0;) - while ((c = getopt_long($1, $2, "SHORT_OPTS", - long_options, NULL)) != EOF) - { - switch (c) - { - default: - ifelse([<$#>],3,$3,[<exit (EX_USAGE)>]); - - undivert(4) - } - } - } ->]) - -define([<STDFUNC>],[< -divert(0) -void print_help(void); -void print_usage(void); -divert(5) -const char *program_version = [<$1>]; -static char doc[] = N_("[<$3>]"); -static char args_doc[] = N_("[<$4>]"); -const char *program_bug_address = "<" PACKAGE_BUGREPORT ">"; - -#define DESCRCOLUMN 30 -#define RMARGIN 79 -#define GROUPCOLUMN 2 -#define USAGECOLUMN 13 - -static void -indent (size_t start, size_t col) -{ - for (; start < col; start++) - putchar (' '); -} - -static void -print_option_descr (const char *descr, size_t lmargin, size_t rmargin) -{ - while (*descr) - { - size_t s = 0; - size_t i; - size_t width = rmargin - lmargin; - - for (i = 0; ; i++) - { - if (descr[i] == 0 || isspace (descr[i])) - { - if (i > width) - break; - s = i; - if (descr[i] == 0) - break; - } - } - printf ("%*.*s\n", s, s, descr); - descr += s; - if (*descr) - { - indent (0, lmargin); - descr++; - } - } -} - -void -print_help(void) -{ - unsigned i; - - printf ("%s %s [%s]... %s\n", _("Usage:"), [<$2>], _("[<OPTION>]"), - gettext (args_doc)); - if (doc[0]) - print_option_descr(gettext (doc), 0, RMARGIN); - putchar ('\n'); - - for (i = 0; i < sizeof (opthelp) / sizeof (opthelp[0]); i++) - { - unsigned n; - if (opthelp[i].opt) - { - n = printf (" %s", opthelp[i].opt); - if (opthelp[i].arg) - { - char *cb, *ce, *sep = ""; - if (opthelp[i].is_optional) - { - cb = "["; - ce = "]"; - } - else - cb = ce = ""; - - if (strlen (opthelp[i].opt) == 2) - { - if (!opthelp[i].is_optional) - sep = " "; - } - else - sep = "="; - n += printf ("%s%s%s%s", cb, sep, gettext (opthelp[i].arg), ce); - } - if (n >= DESCRCOLUMN) - { - putchar ('\n'); - n = 0; - } - indent (n, DESCRCOLUMN); - print_option_descr (gettext (opthelp[i].descr), DESCRCOLUMN, RMARGIN); - } - else - { - if (i) - putchar ('\n'); - indent (0, GROUPCOLUMN); - print_option_descr (gettext (opthelp[i].descr), - GROUPCOLUMN, RMARGIN); - putchar ('\n'); - } - } - - putchar ('\n'); -dnl ************************************************************************** -dnl This string cannot be split over several lines, because this would trigger -dnl a bug in GNU M4 (version 1.4.9 and 1.4.10), which would insert #line -dnl directives between the lines. -dnl ************************************************************************** - print_option_descr (_("Mandatory or optional arguments to long options are also mandatory or optional for any corresponding short options."), 0, RMARGIN); - putchar ('\n'); - printf (_("Report bugs to %s.\n"), program_bug_address); -} - -void -print_usage(void) -{ - unsigned i; - int f = 0; - unsigned n; - char buf[RMARGIN+1]; - -#define FLUSH dnl - do dnl - { dnl - buf[n] = 0; dnl - printf ("%s\n", buf); dnl - n = USAGECOLUMN; dnl - memset (buf, ' ', n); dnl - } dnl - while (0) -#define ADDC(c) dnl - do { if (n == RMARGIN) FLUSH; buf[n++] = c; } while (0) - - n = snprintf (buf, sizeof buf, "%s %s ", _("Usage:"), [<$2>]); - - /* Print a list of short options without arguments. */ - for (i = 0; i < sizeof (opthelp) / sizeof (opthelp[0]); i++) - { - if (opthelp[i].opt && opthelp[i].descr && opthelp[i].opt[1] != '-' - && opthelp[i].arg == NULL) - { - if (f == 0) - { - ADDC('['); - ADDC('-'); - f = 1; - } - ADDC(opthelp[i].opt[1]); - } - } - if (f) - ADDC(']'); - - /* Print a list of short options with arguments. */ - for (i = 0; i < sizeof (opthelp) / sizeof (opthelp[0]); i++) - { - if (opthelp[i].opt && opthelp[i].descr && opthelp[i].opt[1] != '-' - && opthelp[i].arg) - { - size_t len = 5 - + strlen (opthelp[i].arg) - + (opthelp[i].is_optional ? 2 : 1); - if (n + len > RMARGIN) FLUSH; - buf[n++] = ' '; - buf[n++] = '['; - buf[n++] = '-'; - buf[n++] = opthelp[i].opt[1]; - if (opthelp[i].is_optional) - { - buf[n++] = '['; - strcpy (&buf[n], opthelp[i].arg); - n += strlen (opthelp[i].arg); - buf[n++] = ']'; - } - else - { - buf[n++] = ' '; - strcpy (&buf[n], opthelp[i].arg); - n += strlen (opthelp[i].arg); - } - buf[n++] = ']'; - } - } - - /* Print a list of long options */ - for (i = 0; i < sizeof (opthelp) / sizeof (opthelp[0]); i++) - { - if (opthelp[i].opt && opthelp[i].descr) - { - size_t len; - const char *longopt; - - if (opthelp[i].opt[1] == '-') - longopt = opthelp[i].opt; - else if (opthelp[i].opt[2] == ',') - longopt = opthelp[i].opt + 4; - else - continue; - - len = 3 + strlen (longopt) - + (opthelp[i].arg ? 1 + strlen (opthelp[i].arg) - + (opthelp[i].is_optional ? 2 : 0) : 0); - if (n + len |