diff --git a/common/Makefile.am b/common/Makefile.am
index 9e0f10917..094ebe6e2 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -48,7 +48,6 @@ common_sources = \
mapstrings.c stringhelp.c stringhelp.h \
strlist.c strlist.h \
utf8conv.c utf8conv.h \
- argparse.c argparse.h \
logging.h \
dotlock.c dotlock.h \
mischelp.c mischelp.h \
diff --git a/common/argparse.c b/common/argparse.c
deleted file mode 100644
index b30499bcc..000000000
--- a/common/argparse.c
+++ /dev/null
@@ -1,1663 +0,0 @@
-/* argparse.c - Argument Parser for option handling
- * Copyright (C) 1997-2001, 2006-2008, 2013-2017 Werner Koch
- * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc.
- * Copyright (C) 2015-2017 g10 Code GmbH
- *
- * This file is part of GnuPG.
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This file 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 Lesser General Public License
- * along with this program; if not, see .
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-/* This file may be used as part of GnuPG or standalone. A GnuPG
- build is detected by the presence of the macro GNUPG_MAJOR_VERSION.
- Some feature are only available in the GnuPG build mode.
- */
-
-#ifdef HAVE_CONFIG_H
-#include
-#endif
-/* We don't want to have the macros from gpgrt here until we have
- * completely replaced this module by the one from gpgrt. */
-#undef GPGRT_ENABLE_ARGPARSE_MACROS
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifdef GNUPG_MAJOR_VERSION
-# include "util.h"
-# include "common-defs.h"
-# include "i18n.h"
-# include "mischelp.h"
-# include "stringhelp.h"
-# include "logging.h"
-# include "utf8conv.h"
-#endif /*GNUPG_MAJOR_VERSION*/
-
-#include "argparse.h"
-
-/* GnuPG uses GPLv3+ but a standalone version of this defaults to
- GPLv2+ because that is the license of this file. Change this if
- you include it in a program which uses GPLv3. If you don't want to
- set a copyright string for your usage() you may also hardcode it
- here. */
-#ifndef GNUPG_MAJOR_VERSION
-
-# define ARGPARSE_GPL_VERSION 2
-# define ARGPARSE_CRIGHT_STR "Copyright (C) YEAR NAME"
-
-#else /* Used by GnuPG */
-
-# define ARGPARSE_GPL_VERSION 3
-# define ARGPARSE_CRIGHT_STR "Copyright (C) 2018 Free Software Foundation, Inc."
-
-#endif /*GNUPG_MAJOR_VERSION*/
-
-/* Replacements for standalone builds. */
-#ifndef GNUPG_MAJOR_VERSION
-# ifndef _
-# define _(a) (a)
-# endif
-# ifndef DIM
-# define DIM(v) (sizeof(v)/sizeof((v)[0]))
-# endif
-# define xtrymalloc(a) malloc ((a))
-# define xtryrealloc(a,b) realloc ((a), (b))
-# define xtrystrdup(a) strdup ((a))
-# define xfree(a) free ((a))
-# define log_error my_log_error
-# define log_bug my_log_bug
-# define trim_spaces(a) my_trim_spaces ((a))
-# define map_static_macro_string(a) (a)
-#endif /*!GNUPG_MAJOR_VERSION*/
-
-
-#define ARGPARSE_STR(v) #v
-#define ARGPARSE_STR2(v) ARGPARSE_STR(v)
-
-
-/* Replacements for standalone builds. */
-#ifndef GNUPG_MAJOR_VERSION
-static void
-my_log_error (const char *fmt, ...)
-{
- va_list arg_ptr ;
-
- va_start (arg_ptr, fmt);
- fprintf (stderr, "%s: ", strusage (11));
- vfprintf (stderr, fmt, arg_ptr);
- va_end (arg_ptr);
-}
-
-static void
-my_log_bug (const char *fmt, ...)
-{
- va_list arg_ptr ;
-
- va_start (arg_ptr, fmt);
- fprintf (stderr, "%s: Ohhhh jeeee: ", strusage (11));
- vfprintf (stderr, fmt, arg_ptr);
- va_end (arg_ptr);
- abort ();
-}
-
-/* Return true if the native charset is utf-8. */
-static int
-is_native_utf8 (void)
-{
- return 1;
-}
-
-static char *
-my_trim_spaces (char *str)
-{
- char *string, *p, *mark;
-
- string = str;
- /* Find first non space character. */
- for (p=string; *p && isspace (*(unsigned char*)p) ; p++)
- ;
- /* Move characters. */
- for ((mark = NULL); (*string = *p); string++, p++)
- if (isspace (*(unsigned char*)p))
- {
- if (!mark)
- mark = string;
- }
- else
- mark = NULL;
- if (mark)
- *mark = '\0' ; /* Remove trailing spaces. */
-
- return str ;
-}
-
-#endif /*!GNUPG_MAJOR_VERSION*/
-
-
-
-/*********************************
- * @Summary arg_parse
- * #include "argparse.h"
- *
- * typedef struct {
- * char *argc; pointer to argc (value subject to change)
- * char ***argv; pointer to argv (value subject to change)
- * unsigned flags; Global flags (DO NOT CHANGE)
- * int err; print error about last option
- * 1 = warning, 2 = abort
- * int r_opt; return option
- * int r_type; type of return value (0 = no argument found)
- * union {
- * int ret_int;
- * long ret_long
- * ulong ret_ulong;
- * char *ret_str;
- * } r; Return values
- * struct {
- * int idx;
- * const char *last;
- * void *aliases;
- * } internal; DO NOT CHANGE
- * } ARGPARSE_ARGS;
- *
- * typedef struct {
- * int short_opt;
- * const char *long_opt;
- * unsigned flags;
- * } ARGPARSE_OPTS;
- *
- * int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts );
- *
- * @Description
- * This is my replacement for getopt(). See the example for a typical usage.
- * Global flags are:
- * Bit 0 : Do not remove options form argv
- * Bit 1 : Do not stop at last option but return other args
- * with r_opt set to -1.
- * Bit 2 : Assume options and real args are mixed.
- * Bit 3 : Do not use -- to stop option processing.
- * Bit 4 : Do not skip the first arg.
- * Bit 5 : allow usage of long option with only one dash
- * Bit 6 : ignore --version
- * all other bits must be set to zero, this value is modified by the
- * function, so assume this is write only.
- * Local flags (for each option):
- * Bit 2-0 : 0 = does not take an argument
- * 1 = takes int argument
- * 2 = takes string argument
- * 3 = takes long argument
- * 4 = takes ulong argument
- * Bit 3 : argument is optional (r_type will the be set to 0)
- * Bit 4 : allow 0x etc. prefixed values.
- * Bit 6 : Ignore this option
- * Bit 7 : This is a command and not an option
- * You stop the option processing by setting opts to NULL, the function will
- * then return 0.
- * @Return Value
- * Returns the args.r_opt or 0 if ready
- * r_opt may be -2/-7 to indicate an unknown option/command.
- * @See Also
- * ArgExpand
- * @Notes
- * You do not need to process the options 'h', '--help' or '--version'
- * because this function includes standard help processing; but if you
- * specify '-h', '--help' or '--version' you have to do it yourself.
- * The option '--' stops argument processing; if bit 1 is set the function
- * continues to return normal arguments.
- * To process float args or unsigned args you must use a string args and do
- * the conversion yourself.
- * @Example
- *
- * ARGPARSE_OPTS opts[] = {
- * { 'v', "verbose", 0 },
- * { 'd', "debug", 0 },
- * { 'o', "output", 2 },
- * { 'c', "cross-ref", 2|8 },
- * { 'm', "my-option", 1|8 },
- * { 300, "ignored-long-option, ARGPARSE_OP_IGNORE},
- * { 500, "have-no-short-option-for-this-long-option", 0 },
- * {0} };
- * ARGPARSE_ARGS pargs = { &argc, &argv, 0 }
- *
- * while( ArgParse( &pargs, &opts) ) {
- * switch( pargs.r_opt ) {
- * case 'v': opt.verbose++; break;
- * case 'd': opt.debug++; break;
- * case 'o': opt.outfile = pargs.r.ret_str; break;
- * case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break;
- * case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break;
- * case 500: opt.a_long_one++; break
- * default : pargs.err = 1; break; -- force warning output --
- * }
- * }
- * if( argc > 1 )
- * log_fatal( "Too many args");
- *
- */
-
-typedef struct alias_def_s *ALIAS_DEF;
-struct alias_def_s {
- ALIAS_DEF next;
- char *name; /* malloced buffer with name, \0, value */
- const char *value; /* ptr into name */
-};
-
-
-/* Object to store the names for the --ignore-invalid-option option.
- This is a simple linked list. */
-typedef struct iio_item_def_s *IIO_ITEM_DEF;
-struct iio_item_def_s
-{
- IIO_ITEM_DEF next;
- char name[1]; /* String with the long option name. */
-};
-
-static const char *(*strusage_handler)( int ) = NULL;
-static int (*custom_outfnc) (int, const char *);
-
-static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s);
-static void show_help(ARGPARSE_OPTS *opts, unsigned flags);
-static void show_version(void);
-static int writestrings (int is_error, const char *string, ...)
-#if __GNUC__ >= 4
- __attribute__ ((sentinel(0)))
-#endif
- ;
-
-
-void
-argparse_register_outfnc (int (*fnc)(int, const char *))
-{
- custom_outfnc = fnc;
-}
-
-
-/* Write STRING and all following const char * arguments either to
- stdout or, if IS_ERROR is set, to stderr. The list of strings must
- be terminated by a NULL. */
-static int
-writestrings (int is_error, const char *string, ...)
-{
- va_list arg_ptr;
- const char *s;
- int count = 0;
-
- if (string)
- {
- s = string;
- va_start (arg_ptr, string);
- do
- {
- if (custom_outfnc)
- custom_outfnc (is_error? 2:1, s);
- else
- fputs (s, is_error? stderr : stdout);
- count += strlen (s);
- }
- while ((s = va_arg (arg_ptr, const char *)));
- va_end (arg_ptr);
- }
- return count;
-}
-
-
-static void
-flushstrings (int is_error)
-{
- if (custom_outfnc)
- custom_outfnc (is_error? 2:1, NULL);
- else
- fflush (is_error? stderr : stdout);
-}
-
-
-static void
-initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
-{
- if( !(arg->flags & (1<<15)) )
- {
- /* Initialize this instance. */
- arg->internal.idx = 0;
- arg->internal.last = NULL;
- arg->internal.inarg = 0;
- arg->internal.stopped = 0;
- arg->internal.aliases = NULL;
- arg->internal.cur_alias = NULL;
- arg->internal.iio_list = NULL;
- arg->err = 0;
- arg->flags |= 1<<15; /* Mark as initialized. */
- if ( *arg->argc < 0 )
- log_bug ("invalid argument for arg_parse\n");
- }
-
-
- if (arg->err)
- {
- /* Last option was erroneous. */
- const char *s;
-
- if (filename)
- {
- if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG )
- s = _("argument not expected");
- else if ( arg->r_opt == ARGPARSE_READ_ERROR )
- s = _("read error");
- else if ( arg->r_opt == ARGPARSE_KEYWORD_TOO_LONG )
- s = _("keyword too long");
- else if ( arg->r_opt == ARGPARSE_MISSING_ARG )
- s = _("missing argument");
- else if ( arg->r_opt == ARGPARSE_INVALID_ARG )
- s = _("invalid argument");
- else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND )
- s = _("invalid command");
- else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS )
- s = _("invalid alias definition");
- else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE )
- s = _("out of core");
- else
- s = _("invalid option");
- log_error ("%s:%u: %s\n", filename, *lineno, s);
- }
- else
- {
- s = arg->internal.last? arg->internal.last:"[??]";
-
- if ( arg->r_opt == ARGPARSE_MISSING_ARG )
- log_error (_("missing argument for option \"%.50s\"\n"), s);
- else if ( arg->r_opt == ARGPARSE_INVALID_ARG )
- log_error (_("invalid argument for option \"%.50s\"\n"), s);
- else if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG )
- log_error (_("option \"%.50s\" does not expect an argument\n"), s);
- else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND )
- log_error (_("invalid command \"%.50s\"\n"), s);
- else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_OPTION )
- log_error (_("option \"%.50s\" is ambiguous\n"), s);
- else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_COMMAND )
- log_error (_("command \"%.50s\" is ambiguous\n"),s );
- else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE )
- log_error ("%s\n", _("out of core\n"));
- else
- log_error (_("invalid option \"%.50s\"\n"), s);
- }
- if (arg->err != ARGPARSE_PRINT_WARNING)
- exit (2);
- arg->err = 0;
- }
-
- /* Zero out the return value union. */
- arg->r.ret_str = NULL;
- arg->r.ret_long = 0;
-}
-
-
-static void
-store_alias( ARGPARSE_ARGS *arg, char *name, char *value )
-{
- /* TODO: replace this dummy function with a rea one
- * and fix the problems IRIX has with (ALIAS_DEV)arg..
- * used as lvalue
- */
- (void)arg;
- (void)name;
- (void)value;
-#if 0
- ALIAS_DEF a = xmalloc( sizeof *a );
- a->name = name;
- a->value = value;
- a->next = (ALIAS_DEF)arg->internal.aliases;
- (ALIAS_DEF)arg->internal.aliases = a;
-#endif
-}
-
-
-/* Return true if KEYWORD is in the ignore-invalid-option list. */
-static int
-ignore_invalid_option_p (ARGPARSE_ARGS *arg, const char *keyword)
-{
- IIO_ITEM_DEF item = arg->internal.iio_list;
-
- for (; item; item = item->next)
- if (!strcmp (item->name, keyword))
- return 1;
- return 0;
-}
-
-
-/* Add the keywords up to the next LF to the list of to be ignored
- options. After returning FP will either be at EOF or the next
- character read will be the first of a new line. The function
- returns 0 on success or true on malloc failure. */
-static int
-ignore_invalid_option_add (ARGPARSE_ARGS *arg, FILE *fp)
-{
- IIO_ITEM_DEF item;
- int c;
- char name[100];
- int namelen = 0;
- int ready = 0;
- enum { skipWS, collectNAME, skipNAME, addNAME} state = skipWS;
-
- while (!ready)
- {
- c = getc (fp);
- if (c == '\n')
- ready = 1;
- else if (c == EOF)
- {
- c = '\n';
- ready = 1;
- }
- again:
- switch (state)
- {
- case skipWS:
- if (!isascii (c) || !isspace(c))
- {
- namelen = 0;
- state = collectNAME;
- goto again;
- }
- break;
-
- case collectNAME:
- if (isspace (c))
- {
- state = addNAME;
- goto again;
- }
- else if (namelen < DIM(name)-1)
- name[namelen++] = c;
- else /* Too long. */
- state = skipNAME;
- break;
-
- case skipNAME:
- if (isspace (c))
- {
- state = skipWS;
- goto again;
- }
- break;
-
- case addNAME:
- name[namelen] = 0;
- if (!ignore_invalid_option_p (arg, name))
- {
- item = xtrymalloc (sizeof *item + namelen);
- if (!item)
- return 1;
- strcpy (item->name, name);
- item->next = (IIO_ITEM_DEF)arg->internal.iio_list;
- arg->internal.iio_list = item;
- }
- state = skipWS;
- goto again;
- }
- }
- return 0;
-}
-
-
-/* Clear the entire ignore-invalid-option list. */
-static void
-ignore_invalid_option_clear (ARGPARSE_ARGS *arg)
-{
- IIO_ITEM_DEF item, tmpitem;
-
- for (item = arg->internal.iio_list; item; item = tmpitem)
- {
- tmpitem = item->next;
- xfree (item);
- }
- arg->internal.iio_list = NULL;
-}
-
-
-
-/****************
- * Get options from a file.
- * Lines starting with '#' are comment lines.
- * Syntax is simply a keyword and the argument.
- * Valid keywords are all keywords from the long_opt list without
- * the leading dashes. The special keywords "help", "warranty" and "version"
- * are not valid here.
- * The special keyword "alias" may be used to store alias definitions,
- * which are later expanded like long options.
- * The option
- * ignore-invalid-option OPTIONNAMEs
- * is recognized and updates a list of option which should be ignored if they
- * are not defined.
- * Caller must free returned strings.
- * If called with FP set to NULL command line args are parse instead.
- *
- * Q: Should we allow the syntax
- * keyword = value
- * and accept for boolean options a value of 1/0, yes/no or true/false?
- * Note: Abbreviation of options is here not allowed.
- */
-int
-optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
- ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
-{
- int state, i, c;
- int idx=0;
- char keyword[100];
- char *buffer = NULL;
- size_t buflen = 0;
- int in_alias=0;
- int unread_buf[3]; /* We use an int so that we can store EOF. */
- int unread_buf_count = 0;
-
- if (!fp) /* Divert to arg_parse() in this case. */
- return arg_parse (arg, opts);
-
- initialize (arg, filename, lineno);
-
- /* If the LINENO is zero we assume that we are at the start of a
- * file and we skip over a possible Byte Order Mark. */
- if (!*lineno)
- {
- unread_buf[0] = getc (fp);
- unread_buf[1] = getc (fp);
- unread_buf[2] = getc (fp);
- if (unread_buf[0] != 0xef
- || unread_buf[1] != 0xbb
- || unread_buf[2] != 0xbf)
- unread_buf_count = 3;
- }
-
- /* Find the next keyword. */
- state = i = 0;
- for (;;)
- {
- if (unread_buf_count)
- c = unread_buf[3 - unread_buf_count--];
- else
- c = getc (fp);
- if (c == '\n' || c== EOF )
- {
- if ( c != EOF )
- ++*lineno;
- if (state == -1)
- break;
- else if (state == 2)
- {
- keyword[i] = 0;
- for (i=0; opts[i].short_opt; i++ )
- {
- if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
- break;
- }
- idx = i;
- arg->r_opt = opts[idx].short_opt;
- if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
- {
- state = i = 0;
- continue;
- }
- else if (!opts[idx].short_opt )
- {
- if (!strcmp (keyword, "ignore-invalid-option"))
- {
- /* No argument - ignore this meta option. */
- state = i = 0;
- continue;
- }
- else if (ignore_invalid_option_p (arg, keyword))
- {
- /* This invalid option is in the iio list. */
- state = i = 0;
- continue;
- }
- arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND)
- ? ARGPARSE_INVALID_COMMAND
- : ARGPARSE_INVALID_OPTION);
- }
- else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
- arg->r_type = 0; /* Does not take an arg. */
- else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL) )
- arg->r_type = 0; /* Arg is optional. */
- else
- arg->r_opt = ARGPARSE_MISSING_ARG;
-
- break;
- }
- else if (state == 3)
- {
- /* No argument found. */
- if (in_alias)
- arg->r_opt = ARGPARSE_MISSING_ARG;
- else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
- arg->r_type = 0; /* Does not take an arg. */
- else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL))
- arg->r_type = 0; /* No optional argument. */
- else
- arg->r_opt = ARGPARSE_MISSING_ARG;
-
- break;
- }
- else if (state == 4)
- {
- /* Has an argument. */
- if (in_alias)
- {
- if (!buffer)
- arg->r_opt = ARGPARSE_UNEXPECTED_ARG;
- else
- {
- char *p;
-
- buffer[i] = 0;
- p = strpbrk (buffer, " \t");
- if (p)
- {
- *p++ = 0;
- trim_spaces (p);
- }
- if (!p || !*p)
- {
- xfree (buffer);
- arg->r_opt = ARGPARSE_INVALID_ALIAS;
- }
- else
- {
- store_alias (arg, buffer, p);
- }
- }
- }
- else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
- arg->r_opt = ARGPARSE_UNEXPECTED_ARG;
- else
- {
- char *p;
-
- if (!buffer)
- {
- keyword[i] = 0;
- buffer = xtrystrdup (keyword);
- if (!buffer)
- arg->r_opt = ARGPARSE_OUT_OF_CORE;
- }
- else
- buffer[i] = 0;
-
- if (buffer)
- {
- trim_spaces (buffer);
- p = buffer;
- if (*p == '"')
- {
- /* Remove quotes. */
- p++;
- if (*p && p[strlen(p)-1] == '\"' )
- p[strlen(p)-1] = 0;
- }
- if (!set_opt_arg (arg, opts[idx].flags, p))
- xfree (buffer);
- else
- gpgrt_annotate_leaked_object (buffer);
- }
- }
- break;
- }
- else if (c == EOF)
- {
- ignore_invalid_option_clear (arg);
- if (ferror (fp))
- arg->r_opt = ARGPARSE_READ_ERROR;
- else
- arg->r_opt = 0; /* EOF. */
- break;
- }
- state = 0;
- i = 0;
- }
- else if (state == -1)
- ; /* Skip. */
- else if (state == 0 && isascii (c) && isspace(c))
- ; /* Skip leading white space. */
- else if (state == 0 && c == '#' )
- state = 1; /* Start of a comment. */
- else if (state == 1)
- ; /* Skip comments. */
- else if (state == 2 && isascii (c) && isspace(c))
- {
- /* Check keyword. */
- keyword[i] = 0;
- for (i=0; opts[i].short_opt; i++ )
- if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
- break;
- idx = i;
- arg->r_opt = opts[idx].short_opt;
- if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
- {
- state = 1; /* Process like a comment. */
- }
- else if (!opts[idx].short_opt)
- {
- if (!strcmp (keyword, "alias"))
- {
- in_alias = 1;
- state = 3;
- }
- else if (!strcmp (keyword, "ignore-invalid-option"))
- {
- if (ignore_invalid_option_add (arg, fp))
- {
- arg->r_opt = ARGPARSE_OUT_OF_CORE;
- break;
- }
- state = i = 0;
- ++*lineno;
- }
- else if (ignore_invalid_option_p (arg, keyword))
- state = 1; /* Process like a comment. */
- else
- {
- arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND)
- ? ARGPARSE_INVALID_COMMAND
- : ARGPARSE_INVALID_OPTION);
- state = -1; /* Skip rest of line and leave. */
- }
- }
- else
- state = 3;
- }
- else if (state == 3)
- {
- /* Skip leading spaces of the argument. */
- if (!isascii (c) || !isspace(c))
- {
- i = 0;
- keyword[i++] = c;
- state = 4;
- }
- }
- else if (state == 4)
- {
- /* Collect the argument. */
- if (buffer)
- {
- if (i < buflen-1)
- buffer[i++] = c;
- else
- {
- char *tmp;
- size_t tmplen = buflen + 50;
-
- tmp = xtryrealloc (buffer, tmplen);
- if (tmp)
- {
- buflen = tmplen;
- buffer = tmp;
- buffer[i++] = c;
- }
- else
- {
- xfree (buffer);
- arg->r_opt = ARGPARSE_OUT_OF_CORE;
- break;
- }
- }
- }
- else if (i < DIM(keyword)-1)
- keyword[i++] = c;
- else
- {
- size_t tmplen = DIM(keyword) + 50;
- buffer = xtrymalloc (tmplen);
- if (buffer)
- {
- buflen = tmplen;
- memcpy(buffer, keyword, i);
- buffer[i++] = c;
- }
- else
- {
- arg->r_opt = ARGPARSE_OUT_OF_CORE;
- break;
- }
- }
- }
- else if (i >= DIM(keyword)-1)
- {
- arg->r_opt = ARGPARSE_KEYWORD_TOO_LONG;
- state = -1; /* Skip rest of line and leave. */
- }
- else
- {
- keyword[i++] = c;
- state = 2;
- }
- }
-
- return arg->r_opt;
-}
-
-
-
-static int
-find_long_option( ARGPARSE_ARGS *arg,
- ARGPARSE_OPTS *opts, const char *keyword )
-{
- int i;
- size_t n;
-
- (void)arg;
-
- /* Would be better if we can do a binary search, but it is not
- possible to reorder our option table because we would mess
- up our help strings - What we can do is: Build a nice option
- lookup table when this function is first invoked */
- if( !*keyword )
- return -1;
- for(i=0; opts[i].short_opt; i++ )
- if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) )
- return i;
-#if 0
- {
- ALIAS_DEF a;
- /* see whether it is an alias */
- for( a = args->internal.aliases; a; a = a->next ) {
- if( !strcmp( a->name, keyword) ) {
- /* todo: must parse the alias here */
- args->internal.cur_alias = a;
- return -3; /* alias available */
- }
- }
- }
-#endif
- /* not found, see whether it is an abbreviation */
- /* aliases may not be abbreviated */
- n = strlen( keyword );
- for(i=0; opts[i].short_opt; i++ ) {
- if( opts[i].long_opt && !strncmp( opts[i].long_opt, keyword, n ) ) {
- int j;
- for(j=i+1; opts[j].short_opt; j++ ) {
- if( opts[j].long_opt
- && !strncmp( opts[j].long_opt, keyword, n )
- && !(opts[j].short_opt == opts[i].short_opt
- && opts[j].flags == opts[i].flags ) )
- return -2; /* abbreviation is ambiguous */
- }
- return i;
- }
- }
- return -1; /* Not found. */
-}
-
-int
-arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
-{
- int idx;
- int argc;
- char **argv;
- char *s, *s2;
- int i;
-
- /* Fill in missing standard options: help, version, warranty and
- * dump-options. */
- ARGPARSE_OPTS help_opt
- = ARGPARSE_s_n (ARGPARSE_SHORTOPT_HELP, "help", "@");
- ARGPARSE_OPTS version_opt
- = ARGPARSE_s_n (ARGPARSE_SHORTOPT_VERSION, "version", "@");
- ARGPARSE_OPTS warranty_opt
- = ARGPARSE_s_n (ARGPARSE_SHORTOPT_WARRANTY, "warranty", "@");
- ARGPARSE_OPTS dump_options_opt
- = ARGPARSE_s_n(ARGPARSE_SHORTOPT_DUMP_OPTIONS, "dump-options", "@");
- int seen_help = 0;
- int seen_version = 0;
- int seen_warranty = 0;
- int seen_dump_options = 0;
-
- i = 0;
- while (opts[i].short_opt)
- {
- if (opts[i].long_opt)
- {
- if (!strcmp(opts[i].long_opt, help_opt.long_opt))
- seen_help = 1;
- else if (!strcmp(opts[i].long_opt, version_opt.long_opt))
- seen_version = 1;
- else if (!strcmp(opts[i].long_opt, warranty_opt.long_opt))
- seen_warranty = 1;
- else if (!strcmp(opts[i].long_opt, dump_options_opt.long_opt))
- seen_dump_options = 1;
- }
- i++;
- }
- if (! seen_help)
- opts[i++] = help_opt;
- if (! seen_version)
- opts[i++] = version_opt;
- if (! seen_warranty)
- opts[i++] = warranty_opt;
- if (! seen_dump_options)
- opts[i++] = dump_options_opt;
-
- initialize( arg, NULL, NULL );
- argc = *arg->argc;
- argv = *arg->argv;
- idx = arg->internal.idx;
-
- if (!idx && argc && !(arg->flags & ARGPARSE_FLAG_ARG0))
- {
- /* Skip the first argument. */
- argc--; argv++; idx++;
- }
-
- next_one:
- if (!argc)
- {
- /* No more args. */
- arg->r_opt = 0;
- goto leave; /* Ready. */
- }
-
- s = *argv;
- arg->internal.last = s;
-
- if (arg->internal.stopped && (arg->flags & ARGPARSE_FLAG_ALL))
- {
- arg->r_opt = ARGPARSE_IS_ARG; /* Not an option but an argument. */
- arg->r_type = 2;
- arg->r.ret_str = s;
- argc--; argv++; idx++; /* set to next one */
- }
- else if( arg->internal.stopped )
- {
- arg->r_opt = 0;
- goto leave; /* Ready. */
- }
- else if ( *s == '-' && s[1] == '-' )
- {
- /* Long option. */
- char *argpos;
-
- arg->internal.inarg = 0;
- if (!s[2] && !(arg->flags & ARGPARSE_FLAG_NOSTOP))
- {
- /* Stop option processing. */
- arg->internal.stopped = 1;
- arg->flags |= ARGPARSE_FLAG_STOP_SEEN;
- argc--; argv++; idx++;
- goto next_one;
- }
-
- argpos = strchr( s+2, '=' );
- if ( argpos )
- *argpos = 0;
- i = find_long_option ( arg, opts, s+2 );
- if ( argpos )
- *argpos = '=';
-
- if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_HELP)
- show_help (opts, arg->flags);
- else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_VERSION)
- {
- if (!(arg->flags & ARGPARSE_FLAG_NOVERSION))
- {
- show_version ();
- exit(0);
- }
- }
- else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_WARRANTY)
- {
- writestrings (0, strusage (16), "\n", NULL);
- exit (0);
- }
- else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_DUMP_OPTIONS)
- {
- for (i=0; opts[i].short_opt; i++ )
- {
- if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE))
- writestrings (0, "--", opts[i].long_opt, "\n", NULL);
- }
- exit (0);
- }
-
- if ( i == -2 )
- arg->r_opt = ARGPARSE_AMBIGUOUS_OPTION;
- else if ( i == -1 )
- {
- arg->r_opt = ARGPARSE_INVALID_OPTION;
- arg->r.ret_str = s+2;
- }
- else
- arg->r_opt = opts[i].short_opt;
- if ( i < 0 )
- ;
- else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
- {
- if ( argpos )
- {
- s2 = argpos+1;
- if ( !*s2 )
- s2 = NULL;
- }
- else
- s2 = argv[1];
- if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
- {
- arg->r_type = ARGPARSE_TYPE_NONE; /* Argument is optional. */
- }
- else if ( !s2 )
- {
- arg->r_opt = ARGPARSE_MISSING_ARG;
- }
- else if ( !argpos && *s2 == '-'
- && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
- {
- /* The argument is optional and the next seems to be an
- option. We do not check this possible option but
- assume no argument */
- arg->r_type = ARGPARSE_TYPE_NONE;
- }
- else
- {
- set_opt_arg (arg, opts[i].flags, s2);
- if ( !argpos )
- {
- argc--; argv++; idx++; /* Skip one. */
- }
- }
- }
- else
- {
- /* Does not take an argument. */
- if ( argpos )
- arg->r_type = ARGPARSE_UNEXPECTED_ARG;
- else
- arg->r_type = 0;
- }
- argc--; argv++; idx++; /* Set to next one. */
- }
- else if ( (*s == '-' && s[1]) || arg->internal.inarg )
- {
- /* Short option. */
- int dash_kludge = 0;
-
- i = 0;
- if ( !arg->internal.inarg )
- {
- arg->internal.inarg++;
- if ( (arg->flags & ARGPARSE_FLAG_ONEDASH) )
- {
- for (i=0; opts[i].short_opt; i++ )
- if ( opts[i].long_opt && !strcmp (opts[i].long_opt, s+1))
- {
- dash_kludge = 1;
- break;
- }
- }
- }
- s += arg->internal.inarg;
-
- if (!dash_kludge )
- {
- for (i=0; opts[i].short_opt; i++ )
- if ( opts[i].short_opt == *s )
- break;
- }
-
- if ( !opts[i].short_opt && ( *s == 'h' || *s == '?' ) )
- show_help (opts, arg->flags);
-
- arg->r_opt = opts[i].short_opt;
- if (!opts[i].short_opt )
- {
- arg->r_opt = (opts[i].flags & ARGPARSE_OPT_COMMAND)?
- ARGPARSE_INVALID_COMMAND:ARGPARSE_INVALID_OPTION;
- arg->internal.inarg++; /* Point to the next arg. */
- arg->r.ret_str = s;
- }
- else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
- {
- if ( s[1] && !dash_kludge )
- {
- s2 = s+1;
- set_opt_arg (arg, opts[i].flags, s2);
- }
- else
- {
- s2 = argv[1];
- if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
- {
- arg->r_type = ARGPARSE_TYPE_NONE;
- }
- else if ( !s2 )
- {
- arg->r_opt = ARGPARSE_MISSING_ARG;
- }
- else if ( *s2 == '-' && s2[1]
- && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
- {
- /* The argument is optional and the next seems to
- be an option. We do not check this possible
- option but assume no argument. */
- arg->r_type = ARGPARSE_TYPE_NONE;
- }
- else
- {
- set_opt_arg (arg, opts[i].flags, s2);
- argc--; argv++; idx++; /* Skip one. */
- }
- }
- s = "x"; /* This is so that !s[1] yields false. */
- }
- else
- {
- /* Does not take an argument. */
- arg->r_type = ARGPARSE_TYPE_NONE;
- arg->internal.inarg++; /* Point to the next arg. */
- }
- if ( !s[1] || dash_kludge )
- {
- /* No more concatenated short options. */
- arg->internal.inarg = 0;
- argc--; argv++; idx++;
- }
- }
- else if ( arg->flags & ARGPARSE_FLAG_MIXED )
- {
- arg->r_opt = ARGPARSE_IS_ARG;
- arg->r_type = 2;
- arg->r.ret_str = s;
- argc--; argv++; idx++; /* Set to next one. */
- }
- else
- {
- arg->internal.stopped = 1; /* Stop option processing. */
- goto next_one;
- }
-
- leave:
- *arg->argc = argc;
- *arg->argv = argv;
- arg->internal.idx = idx;
- return arg->r_opt;
-}
-
-
-/* Returns: -1 on error, 0 for an integer type and 1 for a non integer
- type argument. */
-static int
-set_opt_arg (ARGPARSE_ARGS *arg, unsigned flags, char *s)
-{
- int base = (flags & ARGPARSE_OPT_PREFIX)? 0 : 10;
- long l;
-
- switch ( (arg->r_type = (flags & ARGPARSE_TYPE_MASK)) )
- {
- case ARGPARSE_TYPE_LONG:
- case ARGPARSE_TYPE_INT:
- errno = 0;
- l = strtol (s, NULL, base);
- if ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE)
- {
- arg->r_opt = ARGPARSE_INVALID_ARG;
- return -1;
- }
- if (arg->r_type == ARGPARSE_TYPE_LONG)
- arg->r.ret_long = l;
- else if ( (l < 0 && l < INT_MIN) || l > INT_MAX )
- {
- arg->r_opt = ARGPARSE_INVALID_ARG;
- return -1;
- }
- else
- arg->r.ret_int = (int)l;
- return 0;
-
- case ARGPARSE_TYPE_ULONG:
- while (isascii (*s) && isspace(*s))
- s++;
- if (*s == '-')
- {
- arg->r.ret_ulong = 0;
- arg->r_opt = ARGPARSE_INVALID_ARG;
- return -1;
- }
- errno = 0;
- arg->r.ret_ulong = strtoul (s, NULL, base);
- if (arg->r.ret_ulong == ULONG_MAX && errno == ERANGE)
- {
- arg->r_opt = ARGPARSE_INVALID_ARG;
- return -1;
- }
- return 0;
-
- case ARGPARSE_TYPE_STRING:
- default:
- arg->r.ret_str = s;
- return 1;
- }
-}
-
-
-static size_t
-long_opt_strlen( ARGPARSE_OPTS *o )
-{
- size_t n = strlen (o->long_opt);
-
- if ( o->description && *o->description == '|' )
- {
- const char *s;
- int is_utf8 = is_native_utf8 ();
-
- s=o->description+1;
- if ( *s != '=' )
- n++;
- /* For a (mostly) correct length calculation we exclude
- continuation bytes (10xxxxxx) if we are on a native utf8
- terminal. */
- for (; *s && *s != '|'; s++ )
- if ( is_utf8 && (*s&0xc0) != 0x80 )
- n++;
- }
- return n;
-}
-
-
-/****************
- * Print formatted help. The description string has some special
- * meanings:
- * - A description string which is "@" suppresses help output for
- * this option
- * - a description,ine which starts with a '@' and is followed by
- * any other characters is printed as is; this may be used for examples
- * and such.
- * - A description which starts with a '|' outputs the string between this
- * bar and the next one as arguments of the long option.
- */
-static void
-show_help (ARGPARSE_OPTS *opts, unsigned int flags)
-{
- const char *s;
- char tmp[2];
-
- show_version ();
- writestrings (0, "\n", NULL);
- s = strusage (42);
- if (s && *s == '1')
- {
- s = strusage (40);
- writestrings (1, s, NULL);
- if (*s && s[strlen(s)] != '\n')
- writestrings (1, "\n", NULL);
- }
- s = strusage(41);
- writestrings (0, s, "\n", NULL);
- if ( opts[0].description )
- {
- /* Auto format the option description. */
- int i,j, indent;
-
- /* Get max. length of long options. */
- for (i=indent=0; opts[i].short_opt; i++ )
- {
- if ( opts[i].long_opt )
- if ( !opts[i].description || *opts[i].description != '@' )
- if ( (j=long_opt_strlen(opts+i)) > indent && j < 35 )
- indent = j;
- }
-
- /* Example: " -v, --verbose Viele Sachen ausgeben" */
- indent += 10;
- if ( *opts[0].description != '@' )
- writestrings (0, "Options:", "\n", NULL);
- for (i=0; opts[i].short_opt; i++ )
- {
- s = map_static_macro_string (_( opts[i].description ));
- if ( s && *s== '@' && !s[1] ) /* Hide this line. */
- continue;
- if ( s && *s == '@' ) /* Unindented comment only line. */
- {
- for (s++; *s; s++ )
- {
- if ( *s == '\n' )
- {
- if( s[1] )
- writestrings (0, "\n", NULL);
- }
- else
- {
- tmp[0] = *s;
- tmp[1] = 0;
- writestrings (0, tmp, NULL);
- }
- }
- writestrings (0, "\n", NULL);
- continue;
- }
-
- j = 3;
- if ( opts[i].short_opt < 256 )
- {
- tmp[0] = opts[i].short_opt;
- tmp[1] = 0;
- writestrings (0, " -", tmp, NULL );
- if ( !opts[i].long_opt )
- {
- if (s && *s == '|' )
- {
- writestrings (0, " ", NULL); j++;
- for (s++ ; *s && *s != '|'; s++, j++ )
- {
- tmp[0] = *s;
- tmp[1] = 0;
- writestrings (0, tmp, NULL);
- }
- if ( *s )
- s++;
- }
- }
- }
- else
- writestrings (0, " ", NULL);
- if ( opts[i].long_opt )
- {
- tmp[0] = opts[i].short_opt < 256?',':' ';
- tmp[1] = 0;
- j += writestrings (0, tmp, " --", opts[i].long_opt, NULL);
- if (s && *s == '|' )
- {
- if ( *++s != '=' )
- {
- writestrings (0, " ", NULL);
- j++;
- }
- for ( ; *s && *s != '|'; s++, j++ )
- {
- tmp[0] = *s;
- tmp[1] = 0;
- writestrings (0, tmp, NULL);
- }
- if ( *s )
- s++;
- }
- writestrings (0, " ", NULL);
- j += 3;
- }
- for (;j < indent; j++ )
- writestrings (0, " ", NULL);
- if ( s )
- {
- if ( *s && j > indent )
- {
- writestrings (0, "\n", NULL);
- for (j=0;j < indent; j++ )
- writestrings (0, " ", NULL);
- }
- for (; *s; s++ )
- {
- if ( *s == '\n' )
- {
- if ( s[1] )
- {
- writestrings (0, "\n", NULL);
- for (j=0; j < indent; j++ )
- writestrings (0, " ", NULL);
- }
- }
- else
- {
- tmp[0] = *s;
- tmp[1] = 0;
- writestrings (0, tmp, NULL);
- }
- }
- }
- writestrings (0, "\n", NULL);
- }
- if ( (flags & ARGPARSE_FLAG_ONEDASH) )
- writestrings (0, "\n(A single dash may be used "
- "instead of the double ones)\n", NULL);
- }
- if ( (s=strusage(19)) )
- {
- writestrings (0, "\n", NULL);
- writestrings (0, s, NULL);
- }
- flushstrings (0);
- exit(0);
-}
-
-static void
-show_version ()
-{
- const char *s;
- int i;
-
- /* Version line. */
- writestrings (0, strusage (11), NULL);
- if ((s=strusage (12)))
- writestrings (0, " (", s, ")", NULL);
- writestrings (0, " ", strusage (13), "\n", NULL);
- /* Additional version lines. */
- for (i=20; i < 30; i++)
- if ((s=strusage (i)))
- writestrings (0, s, "\n", NULL);
- /* Copyright string. */
- if ((s=strusage (14)))
- writestrings (0, s, "\n", NULL);
- /* Licence string. */
- if( (s=strusage (10)) )
- writestrings (0, s, "\n", NULL);
- /* Copying conditions. */
- if ( (s=strusage(15)) )
- writestrings (0, s, NULL);
- /* Thanks. */
- if ((s=strusage(18)))
- writestrings (0, s, NULL);
- /* Additional program info. */
- for (i=30; i < 40; i++ )
- if ( (s=strusage (i)) )
- writestrings (0, s, NULL);
- flushstrings (0);
-}
-
-
-void
-usage (int level)
-{
- const char *p;
-
- if (!level)
- {
- writestrings (1, strusage(11), " ", strusage(13), "; ",
- strusage (14), "\n", NULL);
- flushstrings (1);
- }
- else if (level == 1)
- {
- p = strusage (40);
- writestrings (1, p, NULL);
- if (*p && p[strlen(p)] != '\n')
- writestrings (1, "\n", NULL);
- exit (2);
- }
- else if (level == 2)
- {
- p = strusage (42);
- if (p && *p == '1')
- {
- p = strusage (40);
- writestrings (1, p, NULL);
- if (*p && p[strlen(p)] != '\n')
- writestrings (1, "\n", NULL);
- }
- writestrings (0, strusage(41), "\n", NULL);
- exit (0);
- }
-}
-
-/* Level
- * 0: Print copyright string to stderr
- * 1: Print a short usage hint to stderr and terminate
- * 2: Print a long usage hint to stdout and terminate
- * 10: Return license info string
- * 11: Return the name of the program
- * 12: Return optional name of package which includes this program.
- * 13: version string
- * 14: copyright string
- * 15: Short copying conditions (with LFs)
- * 16: Long copying conditions (with LFs)
- * 17: Optional printable OS name
- * 18: Optional thanks list (with LFs)
- * 19: Bug report info
- *20..29: Additional lib version strings.
- *30..39: Additional program info (with LFs)
- * 40: short usage note (with LF)
- * 41: long usage note (with LF)
- * 42: Flag string:
- * First char is '1':
- * The short usage notes needs to be printed
- * before the long usage note.
- */
-const char *
-strusage( int level )
-{
- const char *p = strusage_handler? strusage_handler(level) : NULL;
-
- if ( p )
- return map_static_macro_string (p);
-
- switch ( level )
- {
-
- case 10:
-#if ARGPARSE_GPL_VERSION == 3
- p = ("License GPLv3+: GNU GPL version 3 or later "
- "");
-#else
- p = ("License GPLv2+: GNU GPL version 2 or later "
- "");
-#endif
- break;
- case 11: p = "foo"; break;
- case 13: p = "0.0"; break;
- case 14: p = ARGPARSE_CRIGHT_STR; break;
- case 15: p =
-"This is free software: you are free to change and redistribute it.\n"
-"There is NO WARRANTY, to the extent permitted by law.\n";
- break;
- case 16: p =
-"This is free software; you can redistribute it and/or modify\n"
-"it under the terms of the GNU General Public License as published by\n"
-"the Free Software Foundation; either version "
-ARGPARSE_STR2(ARGPARSE_GPL_VERSION)
-" of the License, or\n"
-"(at your option) any later version.\n\n"
-"It is distributed in the hope that it will be useful,\n"
-"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
-"GNU General Public License for more details.\n\n"
-"You should have received a copy of the GNU General Public License\n"
-"along with this software. If not, see .\n";
- break;
- case 40: /* short and long usage */
- case 41: p = ""; break;
- }
-
- return p;
-}
-
-
-/* Set the usage handler. This function is basically a constructor. */
-void
-set_strusage ( const char *(*f)( int ) )
-{
- strusage_handler = f;
-}
-
-
-#ifdef TEST
-static struct {
- int verbose;
- int debug;
- char *outfile;
- char *crf;
- int myopt;
- int echo;
- int a_long_one;
-} opt;
-
-int
-main(int argc, char **argv)
-{
- ARGPARSE_OPTS opts[] = {
- ARGPARSE_x('v', "verbose", NONE, 0, "Laut sein"),
- ARGPARSE_s_n('e', "echo" , ("Zeile ausgeben, damit wir sehen, "
- "was wir eingegeben haben")),
- ARGPARSE_s_n('d', "debug", "Debug\nfalls mal etwas\nschief geht"),
- ARGPARSE_s_s('o', "output", 0 ),
- ARGPARSE_o_s('c', "cross-ref", "cross-reference erzeugen\n" ),
- /* Note that on a non-utf8 terminal the ß might garble the output. */
- ARGPARSE_s_n('s', "street","|Straße|set the name of the street to Straße"),
- ARGPARSE_o_i('m', "my-option", 0),
- ARGPARSE_s_n(500, "a-long-option", 0 ),
- ARGPARSE_end()
- };
- ARGPARSE_ARGS pargs = { &argc, &argv, (ARGPARSE_FLAG_ALL
- | ARGPARSE_FLAG_MIXED
- | ARGPARSE_FLAG_ONEDASH) };
- int i;
-
- while (arg_parse (&pargs, opts))
- {
- switch (pargs.r_opt)
- {
- case ARGPARSE_IS_ARG :
- printf ("arg='%s'\n", pargs.r.ret_str);
- break;
- case 'v': opt.verbose++; break;
- case 'e': opt.echo++; break;
- case 'd': opt.debug++; break;
- case 'o': opt.outfile = pargs.r.ret_str; break;
- case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break;
- case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break;
- case 500: opt.a_long_one++; break;
- default : pargs.err = ARGPARSE_PRINT_WARNING; break;
- }
- }
- for (i=0; i < argc; i++ )
- printf ("%3d -> (%s)\n", i, argv[i] );
- puts ("Options:");
- if (opt.verbose)
- printf (" verbose=%d\n", opt.verbose );
- if (opt.debug)
- printf (" debug=%d\n", opt.debug );
- if (opt.outfile)
- printf (" outfile='%s'\n", opt.outfile );
- if (opt.crf)
- printf (" crffile='%s'\n", opt.crf );
- if (opt.myopt)
- printf (" myopt=%d\n", opt.myopt );
- if (opt.a_long_one)
- printf (" a-long-one=%d\n", opt.a_long_one );
- if (opt.echo)
- printf (" echo=%d\n", opt.echo );
-
- return 0;
-}
-#endif /*TEST*/
-
-/**** bottom of file ****/
diff --git a/common/argparse.h b/common/argparse.h
deleted file mode 100644
index 4167d667a..000000000
--- a/common/argparse.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/* argparse.h - Argument parser for option handling.
- * Copyright (C) 1997-2001, 2006-2008, 2013-2017 Werner Koch
- * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc.
- * Copyright (C) 2015-2017 g10 Code GmbH
- *
- * This file is part of GnuPG.
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This file 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 Lesser General Public License
- * along with this program; if not, see .
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#ifndef GNUPG_COMMON_ARGPARSE_H
-#define GNUPG_COMMON_ARGPARSE_H
-
-#include
-
-typedef struct
-{
- int *argc; /* Pointer to ARGC (value subject to change). */
- char ***argv; /* Pointer to ARGV (value subject to change). */
- unsigned int flags; /* Global flags. May be set prior to calling the
- parser. The parser may change the value. */
- int err; /* Print error description for last option.
- Either 0, ARGPARSE_PRINT_WARNING or
- ARGPARSE_PRINT_ERROR. */
-
- int r_opt; /* Returns option code. */
- int r_type; /* Returns type of option value. */
- union {
- int ret_int;
- long ret_long;
- unsigned long ret_ulong;
- char *ret_str;
- } r; /* Return values */
-
- struct {
- int idx;
- int inarg;
- int stopped;
- const char *last;
- void *aliases;
- const void *cur_alias;
- void *iio_list;
- } internal; /* Private - do not change. */
-} ARGPARSE_ARGS;
-
-typedef struct
-{
- int short_opt;
- const char *long_opt;
- unsigned int flags;
- const char *description; /* Optional option description. */
-} ARGPARSE_OPTS;
-
-/* Short options. */
-#define ARGPARSE_SHORTOPT_HELP 32768
-#define ARGPARSE_SHORTOPT_VERSION 32769
-#define ARGPARSE_SHORTOPT_WARRANTY 32770
-#define ARGPARSE_SHORTOPT_DUMP_OPTIONS 32771
-
-
-/* Global flags (ARGPARSE_ARGS). */
-#define ARGPARSE_FLAG_KEEP 1 /* Do not remove options form argv. */
-#define ARGPARSE_FLAG_ALL 2 /* Do not stop at last option but return
- remaining args with R_OPT set to -1. */
-#define ARGPARSE_FLAG_MIXED 4 /* Assume options and args are mixed. */
-#define ARGPARSE_FLAG_NOSTOP 8 /* Do not stop processing at "--". */
-#define ARGPARSE_FLAG_ARG0 16 /* Do not skip the first arg. */
-#define ARGPARSE_FLAG_ONEDASH 32 /* Allow long options with one dash. */
-#define ARGPARSE_FLAG_NOVERSION 64 /* No output for "--version". */
-
-#define ARGPARSE_FLAG_STOP_SEEN 256 /* Set to true if a "--" has been seen. */
-
-/* Flags for each option (ARGPARSE_OPTS). The type code may be
- ORed with the OPT flags. */
-#define ARGPARSE_TYPE_NONE 0 /* Does not take an argument. */
-#define ARGPARSE_TYPE_INT 1 /* Takes an int argument. */
-#define ARGPARSE_TYPE_STRING 2 /* Takes a string argument. */
-#define ARGPARSE_TYPE_LONG 3 /* Takes a long argument. */
-#define ARGPARSE_TYPE_ULONG 4 /* Takes an unsigned long argument. */
-#define ARGPARSE_OPT_OPTIONAL (1<<3) /* Argument is optional. */
-#define ARGPARSE_OPT_PREFIX (1<<4) /* Allow 0x etc. prefixed values. */
-#define ARGPARSE_OPT_IGNORE (1<<6) /* Ignore command or option. */
-#define ARGPARSE_OPT_COMMAND (1<<7) /* The argument is a command. */
-
-#define ARGPARSE_TYPE_MASK 7 /* Mask for the type values (internal). */
-
-/* A set of macros to make option definitions easier to read. */
-#define ARGPARSE_x(s,l,t,f,d) \
- { (s), (l), ARGPARSE_TYPE_ ## t | (f), (d) }
-
-#define ARGPARSE_s(s,l,t,d) \
- { (s), (l), ARGPARSE_TYPE_ ## t, (d) }
-#define ARGPARSE_s_n(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_NONE, (d) }
-#define ARGPARSE_s_i(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_INT, (d) }
-#define ARGPARSE_s_s(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_STRING, (d) }
-#define ARGPARSE_s_l(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_LONG, (d) }
-#define ARGPARSE_s_u(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_ULONG, (d) }
-
-#define ARGPARSE_o(s,l,t,d) \
- { (s), (l), (ARGPARSE_TYPE_ ## t | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_n(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_i(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_INT | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_s(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_STRING | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_l(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_LONG | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_u(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_ULONG | ARGPARSE_OPT_OPTIONAL), (d) }
-
-#define ARGPARSE_p(s,l,t,d) \
- { (s), (l), (ARGPARSE_TYPE_ ## t | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_n(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_i(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_INT | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_s(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_STRING | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_l(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_LONG | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_u(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_ULONG | ARGPARSE_OPT_PREFIX), (d) }
-
-#define ARGPARSE_op(s,l,t,d) \
- { (s), (l), (ARGPARSE_TYPE_ ## t \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_n(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_NONE \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_i(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_INT \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_s(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_STRING \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_l(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_LONG \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_u(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_ULONG \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-
-#define ARGPARSE_c(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_COMMAND), (d) }
-
-#define ARGPARSE_ignore(s,l) \
- { (s), (l), (ARGPARSE_OPT_IGNORE), "@" }
-
-#define ARGPARSE_group(s,d) \
- { (s), NULL, 0, (d) }
-
-/* Placeholder options for help, version, warranty and dump-options. See arg_parse(). */
-#define ARGPARSE_end() \
- { 0, NULL, 0, NULL }, \
- { 0, NULL, 0, NULL }, \
- { 0, NULL, 0, NULL }, \
- { 0, NULL, 0, NULL }, \
- { 0, NULL, 0, NULL }
-
-
-/* Other constants. */
-#define ARGPARSE_PRINT_WARNING 1
-#define ARGPARSE_PRINT_ERROR 2
-
-
-/* Error values. */
-#define ARGPARSE_IS_ARG (-1)
-#define ARGPARSE_INVALID_OPTION (-2)
-#define ARGPARSE_MISSING_ARG (-3)
-#define ARGPARSE_KEYWORD_TOO_LONG (-4)
-#define ARGPARSE_READ_ERROR (-5)
-#define ARGPARSE_UNEXPECTED_ARG (-6)
-#define ARGPARSE_INVALID_COMMAND (-7)
-#define ARGPARSE_AMBIGUOUS_OPTION (-8)
-#define ARGPARSE_AMBIGUOUS_COMMAND (-9)
-#define ARGPARSE_INVALID_ALIAS (-10)
-#define ARGPARSE_OUT_OF_CORE (-11)
-#define ARGPARSE_INVALID_ARG (-12)
-
-
-int arg_parse (ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
-int optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
- ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
-void usage (int level);
-const char *strusage (int level);
-void set_strusage (const char *(*f)( int ));
-void argparse_register_outfnc (int (*fnc)(int, const char *));
-
-#endif /*GNUPG_COMMON_ARGPARSE_H*/
diff --git a/common/init.c b/common/init.c
index f62c5cd58..073c5cd8a 100644
--- a/common/init.c
+++ b/common/init.c
@@ -210,7 +210,6 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
}
/* --version et al shall use estream as well. */
- argparse_register_outfnc (writestring_via_estream); /* legacy. */
gpgrt_set_usage_outfnc (writestring_via_estream);
/* Register our string mapper with gpgrt. */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e35a7938d..0f12f53fb 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -25,7 +25,6 @@ common/helpfile.c
common/gettime.c
common/ksba-io-support.c
-common/argparse.c
common/utf8conv.c
common/dotlock.c
common/init.c
diff --git a/tests/gpgscm/main.c b/tests/gpgscm/main.c
index dc176c302..bd579c43f 100644
--- a/tests/gpgscm/main.c
+++ b/tests/gpgscm/main.c
@@ -16,12 +16,10 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
+ * SPDX-License-Identifier: GPL-3.0-or-later
*/
#include
-/* We don't want to have the macros from gpgrt here until we have
- * completely replaced this module by the one from gpgrt. */
-#undef GPGRT_ENABLE_ARGPARSE_MACROS
#include
#include
@@ -45,13 +43,11 @@
#include "scheme-private.h"
#include "ffi.h"
#include "../common/i18n.h"
-#include "../../common/argparse.h"
#include "../../common/init.h"
#include "../../common/logging.h"
#include "../../common/strlist.h"
#include "../../common/sysutils.h"
#include "../../common/util.h"
-#include "../common/argparse.h" /* temporary hack. */
/* The TinyScheme banner. Unfortunately, it isn't in the header
file. */
@@ -69,7 +65,7 @@ enum cmd_and_opt_values
};
/* The list of commands and options. */
-static ARGPARSE_OPTS opts[] =
+static gpgrt_opt_t opts[] =
{
ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
ARGPARSE_end (),
@@ -80,11 +76,9 @@ size_t scmpath_len = 0;
/* Command line parsing. */
static void
-parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
+parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts)
{
- int no_more_options = 0;
-
- while (!no_more_options && optfile_parse (NULL, NULL, NULL, pargs, popts))
+ while (gpgrt_argparse (NULL, pargs, popts))
{
switch (pargs->r_opt)
{
@@ -93,7 +87,7 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
break;
default:
- pargs->err = 2;
+ pargs->err = ARGPARSE_PRINT_ERROR;
break;
}
}
@@ -107,9 +101,11 @@ my_strusage( int level )
switch (level)
{
+ case 9: p = "GPL-3.0-or-later"; break;
case 11: p = "gpgscm (@GNUPG@)";
break;
case 13: p = VERSION; break;
+ case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
@@ -256,7 +252,7 @@ main (int argc, char **argv)
int retcode;
gpg_error_t err;
char *argv0;
- ARGPARSE_ARGS pargs;
+ gpgrt_argparse_t pargs;
scheme *sc;
char *p;
#if _WIN32
@@ -283,7 +279,7 @@ main (int argc, char **argv)
if (*p == pathsep)
*p = 0, scmpath_len++;
- set_strusage (my_strusage);
+ gpgrt_set_strusage (my_strusage);
log_set_prefix ("gpgscm", GPGRT_LOG_WITH_PREFIX);
/* Make sure that our subsystems are ready. */
@@ -301,6 +297,7 @@ main (int argc, char **argv)
pargs.argv = &argv;
pargs.flags = 0;
parse_arguments (&pargs, opts);
+ gpgrt_argparse (NULL, &pargs, NULL);
if (log_get_errorcount (0))
exit (2);