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

   Copyright (C) 1990, 1998, 1999, 2001, 2002, 2003, 2004, 2005 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.

   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, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by David MacKenzie <djm@ai.mit.edu>
   Modified by Akim Demaille <demaille@inf.enst.fr> */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

/* 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 "exit.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
