tmpdir: Use a good default directory on native Windows.
[gnulib.git] / lib / argmatch.c
index 3578784..9a3eca4 100644 (file)
@@ -1,10 +1,12 @@
 /* argmatch.c -- find a match for a string in an array
 /* argmatch.c -- find a match for a string in an array
-   Copyright (C) 1990, 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
 
 
-   This program is free software; you can redistribute it and/or modify
+   Copyright (C) 1990, 1998-1999, 2001-2007, 2009-2011 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
    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
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    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 <http://www.gnu.org/licenses/>.  */
 
 /* Written by David MacKenzie <djm@ai.mit.edu>
    Modified by Akim Demaille <demaille@inf.enst.fr> */
 
 
 /* Written by David MacKenzie <djm@ai.mit.edu>
    Modified by Akim Demaille <demaille@inf.enst.fr> */
 
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <config.h>
 
 
+/* Specification.  */
 #include "argmatch.h"
 
 #include "argmatch.h"
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "error.h"
 #include "quotearg.h"
 #include "quote.h"
 #include "error.h"
 #include "quotearg.h"
 #include "quote.h"
-#include "unlocked-io.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
 
 /* When reporting an invalid argument, show nonprinting characters
    by using the quoting style ARGMATCH_QUOTING_STYLE.  Do not use
@@ -45,7 +49,8 @@
 
 /* Non failing version of argmatch call this function after failing. */
 #ifndef ARGMATCH_DIE
 
 /* 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
 #endif
 
 #ifdef ARGMATCH_DIE_DECL
@@ -64,10 +69,9 @@ argmatch_exit_fn argmatch_die = __argmatch_die;
 
 \f
 /* If ARG is an unambiguous match for an element of the
 
 \f
 /* 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).
    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
 
    If VALLIST is none null, use it to resolve ambiguities limited to
    synonyms, i.e., for
@@ -75,44 +79,41 @@ argmatch_exit_fn argmatch_die = __argmatch_die;
      "no", "nope" -> 1
    "y" is a valid argument, for `0', and "n" for `1'.  */
 
      "no", "nope" -> 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++)
     {
 
   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;
     }
   if (ambiguous)
     return -2;
@@ -120,36 +121,20 @@ __argmatch_internal (const char *arg, const char *const *arglist,
     return matchind;
 }
 
     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
 /* 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
 {
   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_n_style (0, ARGMATCH_QUOTING_STYLE, value),
 
   error (0, 0, format, quotearg_n_style (0, ARGMATCH_QUOTING_STYLE, value),
-        quote_n (1, context));
+         quote_n (1, context));
 }
 
 /* List the valid arguments for argmatch.
 }
 
 /* List the valid arguments for argmatch.
@@ -158,9 +143,9 @@ 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,
    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
   const char *last_val = NULL;
 
   /* We try to put synonyms on the same line.  The assumption is that
@@ -168,14 +153,14 @@ argmatch_valid (const char *const *arglist,
   fprintf (stderr, _("Valid arguments are:"));
   for (i = 0; arglist[i]; i++)
     if ((i == 0)
   fprintf (stderr, _("Valid arguments are:"));
   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'", arglist[i]);
+        last_val = vallist + valsize * i;
       }
     else
       {
       }
     else
       {
-       fprintf (stderr, ", `%s'", arglist[i]);
+        fprintf (stderr, ", `%s'", arglist[i]);
       }
   putc ('\n', stderr);
 }
       }
   putc ('\n', stderr);
 }
@@ -186,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. */
 
    "--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,
 __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;
   if (res >= 0)
     /* Success. */
     return res;
@@ -212,10 +194,10 @@ __xargmatch_internal (const char *context,
    return the first corresponding argument in ARGLIST */
 const char *
 argmatch_to_argument (const char *value,
    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))
 
   for (i = 0; arglist[i]; i++)
     if (!memcmp (value, vallist + valsize * i, valsize))
@@ -228,23 +210,22 @@ argmatch_to_argument (const char *value,
  * Based on "getversion.c" by David MacKenzie <djm@gnu.ai.mit.edu>
  */
 char *program_name;
  * Based on "getversion.c" by David MacKenzie <djm@gnu.ai.mit.edu>
  */
 char *program_name;
-extern const char *getenv ();
 
 /* When to make backup files.  */
 enum backup_type
 {
   /* Never make backups.  */
 
 /* When to make backup files.  */
 enum backup_type
 {
   /* Never make backups.  */
-  none,
+  no_backups,
 
   /* Make simple backups of every file.  */
 
   /* 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.  */
 
   /* 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.  */
 
   /* Make numbered backups of every file.  */
-  numbered
+  numbered_backups
 };
 
 /* Two tables describing arguments (keys) and their corresponding
 };
 
 /* Two tables describing arguments (keys) and their corresponding
@@ -260,17 +241,17 @@ static const char *const backup_args[] =
 
 static const enum backup_type backup_vals[] =
 {
 
 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;
 };
 
 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];
 
 
   program_name = (char *) argv[0];
 
@@ -281,15 +262,15 @@ main (int argc, const char *const *argv)
     }
 
   if ((cp = getenv ("VERSION_CONTROL")))
     }
 
   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)
 
   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",
 
   printf ("The version control is `%s'\n",
-         ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals));
+          ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals));
 
   return 0;
 }
 
   return 0;
 }