Index: bison/src/bison/2.4.1/bison-2.4.1-src/lib/argmatch.c |
=================================================================== |
--- bison/src/bison/2.4.1/bison-2.4.1-src/lib/argmatch.c (revision 0) |
+++ bison/src/bison/2.4.1/bison-2.4.1-src/lib/argmatch.c (revision 0) |
@@ -0,0 +1,277 @@ |
+/* argmatch.c -- find a match for a string in an array |
+ |
+ Copyright (C) 1990, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007 |
+ 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 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 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ GNU General Public License for more details. |
+ |
+ You should have received a copy of the GNU General Public License |
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
+ |
+/* Written by David MacKenzie <djm@ai.mit.edu> |
+ Modified by Akim Demaille <demaille@inf.enst.fr> */ |
+ |
+#include <config.h> |
+ |
+/* Specification. */ |
+#include "argmatch.h" |
+ |
+#include <stdbool.h> |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+ |
+#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 |
+ literal_quoting_style. */ |
+#ifndef ARGMATCH_QUOTING_STYLE |
+# define ARGMATCH_QUOTING_STYLE locale_quoting_style |
+#endif |
+ |
+/* Non failing version of argmatch call this function after failing. */ |
+#ifndef ARGMATCH_DIE |
+# include "exitfail.h" |
+# define ARGMATCH_DIE exit (exit_failure) |
+#endif |
+ |
+#ifdef ARGMATCH_DIE_DECL |
+ARGMATCH_DIE_DECL; |
+#endif |
+ |
+static void |
+__argmatch_die (void) |
+{ |
+ ARGMATCH_DIE; |
+} |
+ |
+/* Used by XARGMATCH and XARGCASEMATCH. See description in argmatch.h. |
+ Default to __argmatch_die, but allow caller to change this at run-time. */ |
+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 |
+ 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 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'. */ |
+ |
+ptrdiff_t |
+argmatch (const char *arg, const char *const *arglist, |
+ const char *vallist, size_t valsize) |
+{ |
+ 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 (!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; |
+ else |
+ return matchind; |
+} |
+ |
+/* 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, ptrdiff_t problem) |
+{ |
+ char const *format = (problem == -1 |
+ ? _("invalid argument %s for %s") |
+ : _("ambiguous argument %s for %s")); |
+ |
+ error (0, 0, format, quotearg_n_style (0, ARGMATCH_QUOTING_STYLE, value), |
+ quote_n (1, context)); |
+} |
+ |
+/* List the valid arguments for argmatch. |
+ ARGLIST is the same as in argmatch. |
+ VALLIST is a pointer to an array of values. |
+ VALSIZE is the size of the elements of VALLIST */ |
+void |
+argmatch_valid (const char *const *arglist, |
+ const char *vallist, size_t valsize) |
+{ |
+ 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:")); |
+ for (i = 0; arglist[i]; i++) |
+ if ((i == 0) |
+ || memcmp (last_val, vallist + valsize * i, valsize)) |
+ { |
+ fprintf (stderr, "\n - `%s'", arglist[i]); |
+ last_val = vallist + valsize * i; |
+ } |
+ else |
+ { |
+ fprintf (stderr, ", `%s'", arglist[i]); |
+ } |
+ putc ('\n', stderr); |
+} |
+ |
+/* Never failing versions of the previous functions. |
+ |
+ CONTEXT is the context for which argmatch is called (e.g., |
+ "--version-control", or "$VERSION_CONTROL" etc.). Upon failure, |
+ calls the (supposed never to return) function EXIT_FN. */ |
+ |
+ptrdiff_t |
+__xargmatch_internal (const char *context, |
+ const char *arg, const char *const *arglist, |
+ const char *vallist, size_t valsize, |
+ argmatch_exit_fn exit_fn) |
+{ |
+ ptrdiff_t res = argmatch (arg, arglist, vallist, valsize); |
+ if (res >= 0) |
+ /* Success. */ |
+ return res; |
+ |
+ /* We failed. Explain why. */ |
+ argmatch_invalid (context, arg, res); |
+ argmatch_valid (arglist, vallist, valsize); |
+ (*exit_fn) (); |
+ |
+ return -1; /* To please the compilers. */ |
+} |
+ |
+/* Look for VALUE in VALLIST, an array of objects of size VALSIZE and |
+ 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) |
+{ |
+ size_t i; |
+ |
+ for (i = 0; arglist[i]; i++) |
+ if (!memcmp (value, vallist + valsize * i, valsize)) |
+ return arglist[i]; |
+ return NULL; |
+} |
+ |
+#ifdef TEST |
+/* |
+ * Based on "getversion.c" by David MacKenzie <djm@gnu.ai.mit.edu> |
+ */ |
+char *program_name; |
+ |
+/* When to make backup files. */ |
+enum backup_type |
+{ |
+ /* Never make backups. */ |
+ no_backups, |
+ |
+ /* Make simple backups of every file. */ |
+ simple_backups, |
+ |
+ /* Make numbered backups of files that already have numbered backups, |
+ and simple backups of the others. */ |
+ numbered_existing_backups, |
+ |
+ /* Make numbered backups of every file. */ |
+ numbered_backups |
+}; |
+ |
+/* Two tables describing arguments (keys) and their corresponding |
+ values */ |
+static const char *const backup_args[] = |
+{ |
+ "no", "none", "off", |
+ "simple", "never", |
+ "existing", "nil", |
+ "numbered", "t", |
+ 0 |
+}; |
+ |
+static const enum backup_type backup_vals[] = |
+{ |
+ 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 = no_backups; |
+ |
+ program_name = (char *) argv[0]; |
+ |
+ if (argc > 2) |
+ { |
+ fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", program_name); |
+ exit (1); |
+ } |
+ |
+ if ((cp = getenv ("VERSION_CONTROL"))) |
+ backup_type = XARGMATCH ("$VERSION_CONTROL", cp, |
+ backup_args, backup_vals); |
+ |
+ if (argc == 2) |
+ 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)); |
+ |
+ return 0; |
+} |
+#endif |
Property changes on: bison\src\bison\2.4.1\bison-2.4.1-src\lib\argmatch.c |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |