/* argmatch.c -- find a match for a string in an array

   Copyright (C) 1990, 1998-1999, 2001-2007, 2009-2020 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 <https://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>

#define _(msgid) gettext (msgid)

#include "error.h"
#include "quotearg.h"
#include "getprogname.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 void *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 ((char const *) vallist + valsize * matchind,
                             (char const *) 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 void *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 */
  fputs (_("Valid arguments are:"), stderr);
  for (i = 0; arglist[i]; i++)
    if ((i == 0)
        || memcmp (last_val, (char const *) vallist + valsize * i, valsize))
      {
        fprintf (stderr, "\n  - %s", quote (arglist[i]));
        last_val = (char const *) vallist + valsize * i;
      }
    else
      {
        fprintf (stderr, ", %s", quote (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 void *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 void *value,
                      const char *const *arglist,
                      const void *vallist, size_t valsize)
{
  size_t i;

  for (i = 0; arglist[i]; i++)
    if (!memcmp (value, (char const *) vallist + valsize * i, valsize))
      return arglist[i];
  return NULL;
}

#ifdef TEST
/*
 * Based on "getversion.c" by David MacKenzie <djm@gnu.ai.mit.edu>
 */

/* 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;

  if (argc > 2)
    {
      fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", getprogname ());
      exit (1);
    }

  if ((cp = getenv ("VERSION_CONTROL")))
    backup_type = XARGMATCH ("$VERSION_CONTROL", cp,
                             backup_args, backup_vals);

  if (argc == 2)
    backup_type = XARGMATCH (getprogname (), 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
