X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fargmatch.c;h=9125e2af048eee7851e28f47090054fa445f4471;hb=fa1db0dd22768f09a507674a30beb5b8a87bb35f;hp=ba1da3fba64be92ba44a58e8f8bfb2e7deb511f5;hpb=d349992d82f97d614404565ff66e3f8a47b4a568;p=gnulib.git diff --git a/lib/argmatch.c b/lib/argmatch.c index ba1da3fba..9125e2af0 100644 --- a/lib/argmatch.c +++ b/lib/argmatch.c @@ -1,10 +1,12 @@ /* argmatch.c -- find a match for a string in an array - Copyright (C) 1990, 1998, 1999, 2000 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify + Copyright (C) 1990, 1998-1999, 2001-2007, 2009-2013 Free Software + Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,32 +14,31 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ /* Written by David MacKenzie Modified by Akim Demaille */ +#include + +/* Specification. */ #include "argmatch.h" +#include #include -#ifdef STDC_HEADERS -# include -#endif +#include +#include -#if HAVE_LOCALE_H -# include -#endif - -#if ENABLE_NLS -# include -# define _(Text) gettext (Text) -#else -# define _(Text) Text -#endif +#include "gettext.h" +#define _(msgid) gettext (msgid) #include "error.h" #include "quotearg.h" +#include "quote.h" + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif /* When reporting an invalid argument, show nonprinting characters by using the quoting style ARGMATCH_QUOTING_STYLE. Do not use @@ -46,17 +47,10 @@ # define ARGMATCH_QUOTING_STYLE locale_quoting_style #endif -/* The following test is to work around the gross typo in - systems like Sony NEWS-OS Release 4.0C, whereby EXIT_FAILURE - is defined to 0, not 1. */ -#if !EXIT_FAILURE -# undef EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif - /* Non failing version of argmatch call this function after failing. */ #ifndef ARGMATCH_DIE -# define ARGMATCH_DIE exit (EXIT_FAILURE) +# include "exitfail.h" +# define ARGMATCH_DIE exit (exit_failure) #endif #ifdef ARGMATCH_DIE_DECL @@ -75,55 +69,51 @@ argmatch_exit_fn argmatch_die = __argmatch_die; /* If ARG is an unambiguous match for an element of the - null-terminated array ARGLIST, return the index in ARGLIST + NULL-terminated array ARGLIST, return the index in ARGLIST of the matched element, else -1 if it does not match any element or -2 if it is ambiguous (is a prefix of more than one element). - If SENSITIVE, comparison is case sensitive. If VALLIST is none null, use it to resolve ambiguities limited to synonyms, i.e., for "yes", "yop" -> 0 "no", "nope" -> 1 - "y" is a valid argument, for `0', and "n" for `1'. */ + "y" is a valid argument, for 0, and "n" for 1. */ -static int -__argmatch_internal (const char *arg, const char *const *arglist, - const char *vallist, size_t valsize, - int case_sensitive) +ptrdiff_t +argmatch (const char *arg, const char *const *arglist, + const char *vallist, size_t valsize) { - int i; /* Temporary index in ARGLIST. */ - size_t arglen; /* Length of ARG. */ - int matchind = -1; /* Index of first nonexact match. */ - int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */ + size_t i; /* Temporary index in ARGLIST. */ + size_t arglen; /* Length of ARG. */ + ptrdiff_t matchind = -1; /* Index of first nonexact match. */ + bool ambiguous = false; /* If true, multiple nonexact match(es). */ arglen = strlen (arg); /* Test all elements for either exact match or abbreviated matches. */ for (i = 0; arglist[i]; i++) { - if (case_sensitive - ? !strncmp (arglist[i], arg, arglen) - : !strncasecmp (arglist[i], arg, arglen)) - { - if (strlen (arglist[i]) == arglen) - /* Exact match found. */ - return i; - else if (matchind == -1) - /* First nonexact match found. */ - matchind = i; - else - { - /* Second nonexact match found. */ - if (vallist == NULL - || memcmp (vallist + valsize * matchind, - vallist + valsize * i, valsize)) - { - /* There is a real ambiguity, or we could not - disambiguate. */ - ambiguous = 1; - } - } - } + if (!strncmp (arglist[i], arg, arglen)) + { + if (strlen (arglist[i]) == arglen) + /* Exact match found. */ + return i; + else if (matchind == -1) + /* First nonexact match found. */ + matchind = i; + else + { + /* Second nonexact match found. */ + if (vallist == NULL + || memcmp (vallist + valsize * matchind, + vallist + valsize * i, valsize)) + { + /* There is a real ambiguity, or we could not + disambiguate. */ + ambiguous = true; + } + } + } } if (ambiguous) return -2; @@ -131,35 +121,20 @@ __argmatch_internal (const char *arg, const char *const *arglist, return matchind; } -/* argmatch - case sensitive version */ -int -argmatch (const char *arg, const char *const *arglist, - const char *vallist, size_t valsize) -{ - return __argmatch_internal (arg, arglist, vallist, valsize, 1); -} - -/* argcasematch - case insensitive version */ -int -argcasematch (const char *arg, const char *const *arglist, - const char *vallist, size_t valsize) -{ - return __argmatch_internal (arg, arglist, vallist, valsize, 0); -} - /* Error reporting for argmatch. CONTEXT is a description of the type of entity that was being matched. VALUE is the invalid value that was given. PROBLEM is the return value from argmatch. */ void -argmatch_invalid (const char *context, const char *value, int problem) +argmatch_invalid (const char *context, const char *value, ptrdiff_t problem) { char const *format = (problem == -1 - ? _("invalid argument %s for `%s'") - : _("ambiguous argument %s for `%s'")); + ? _("invalid argument %s for %s") + : _("ambiguous argument %s for %s")); - error (0, 0, format, quotearg_style (ARGMATCH_QUOTING_STYLE, value), context); + error (0, 0, format, quotearg_n_style (0, ARGMATCH_QUOTING_STYLE, value), + quote_n (1, context)); } /* List the valid arguments for argmatch. @@ -168,24 +143,24 @@ argmatch_invalid (const char *context, const char *value, int problem) VALSIZE is the size of the elements of VALLIST */ void argmatch_valid (const char *const *arglist, - const char *vallist, size_t valsize) + const char *vallist, size_t valsize) { - int i; + size_t i; const char *last_val = NULL; /* We try to put synonyms on the same line. The assumption is that synonyms follow each other */ - fprintf (stderr, _("Valid arguments are:")); + fputs (_("Valid arguments are:"), stderr); for (i = 0; arglist[i]; i++) if ((i == 0) - || memcmp (last_val, vallist + valsize * i, valsize)) + || memcmp (last_val, vallist + valsize * i, valsize)) { - fprintf (stderr, "\n - `%s'", arglist[i]); - last_val = vallist + valsize * i; + fprintf (stderr, "\n - %s", quote (arglist[i])); + last_val = vallist + valsize * i; } else { - fprintf (stderr, ", `%s'", arglist[i]); + fprintf (stderr, ", %s", quote (arglist[i])); } putc ('\n', stderr); } @@ -196,16 +171,13 @@ argmatch_valid (const char *const *arglist, "--version-control", or "$VERSION_CONTROL" etc.). Upon failure, calls the (supposed never to return) function EXIT_FN. */ -int +ptrdiff_t __xargmatch_internal (const char *context, - const char *arg, const char *const *arglist, - const char *vallist, size_t valsize, - int case_sensitive, - argmatch_exit_fn exit_fn) + const char *arg, const char *const *arglist, + const char *vallist, size_t valsize, + argmatch_exit_fn exit_fn) { - int res = __argmatch_internal (arg, arglist, - vallist, valsize, - case_sensitive); + ptrdiff_t res = argmatch (arg, arglist, vallist, valsize); if (res >= 0) /* Success. */ return res; @@ -222,10 +194,10 @@ __xargmatch_internal (const char *context, return the first corresponding argument in ARGLIST */ const char * argmatch_to_argument (const char *value, - const char *const *arglist, - const char *vallist, size_t valsize) + const char *const *arglist, + const char *vallist, size_t valsize) { - int i; + size_t i; for (i = 0; arglist[i]; i++) if (!memcmp (value, vallist + valsize * i, valsize)) @@ -238,23 +210,22 @@ argmatch_to_argument (const char *value, * Based on "getversion.c" by David MacKenzie */ char *program_name; -extern const char *getenv (); /* When to make backup files. */ enum backup_type { /* Never make backups. */ - none, + no_backups, /* Make simple backups of every file. */ - simple, + simple_backups, /* Make numbered backups of files that already have numbered backups, and simple backups of the others. */ - numbered_existing, + numbered_existing_backups, /* Make numbered backups of every file. */ - numbered + numbered_backups }; /* Two tables describing arguments (keys) and their corresponding @@ -270,17 +241,17 @@ static const char *const backup_args[] = static const enum backup_type backup_vals[] = { - none, none, none, - simple, simple, - numbered_existing, numbered_existing, - numbered, numbered + no_backups, no_backups, no_backups, + simple_backups, simple_backups, + numbered_existing_backups, numbered_existing_backups, + numbered_backups, numbered_backups }; int main (int argc, const char *const *argv) { const char *cp; - enum backup_type backup_type = none; + enum backup_type backup_type = no_backups; program_name = (char *) argv[0]; @@ -291,15 +262,15 @@ main (int argc, const char *const *argv) } if ((cp = getenv ("VERSION_CONTROL"))) - backup_type = XARGCASEMATCH ("$VERSION_CONTROL", cp, - backup_args, backup_vals); + backup_type = XARGMATCH ("$VERSION_CONTROL", cp, + backup_args, backup_vals); if (argc == 2) - backup_type = XARGCASEMATCH (program_name, argv[1], - backup_args, backup_vals); + backup_type = XARGMATCH (program_name, argv[1], + backup_args, backup_vals); - printf ("The version control is `%s'\n", - ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals)); + printf ("The version control is '%s'\n", + ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals)); return 0; }