From cdbe10b762f38449b86da69076209324b0c99982 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 22 Feb 2020 09:51:29 +0100 Subject: [PATCH] Remove the now obsolete argparse code. * tests/gpgscm/main.c: Switch to the new option parser. * common/argparse.c, common/argparse.h: Remove. * common/init.c (_init_common_subsystems): Do not call obsolete func. * common/Makefile.am (common_sources): Remove those files. Signed-off-by: Werner Koch --- common/Makefile.am | 1 - common/argparse.c | 1663 ------------------------------------------- common/argparse.h | 207 ------ common/init.c | 1 - po/POTFILES.in | 1 - tests/gpgscm/main.c | 23 +- 6 files changed, 10 insertions(+), 1886 deletions(-) delete mode 100644 common/argparse.c delete mode 100644 common/argparse.h 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);