/* Determine whether string value is affirmation or negative response
   according to current locale's data.

   Copyright (C) 1996, 1998, 2000, 2002-2003, 2006-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/>.  */

#include <config.h>

/* Specification.  */
#include <stdlib.h>

#include <stdbool.h>
#include <stddef.h>

#if ENABLE_NLS
# include <sys/types.h>
# include <limits.h>
# include <string.h>
# if HAVE_LANGINFO_YESEXPR
#  include <langinfo.h>
# endif
# include <regex.h>
# include "gettext.h"
# define _(msgid) gettext (msgid)
# define N_(msgid) gettext_noop (msgid)

# if HAVE_LANGINFO_YESEXPR
/* Return the localized regular expression pattern corresponding to
   ENGLISH_PATTERN.  NL_INDEX can be used with nl_langinfo.
   The resulting string may only be used until the next nl_langinfo call.  */
static const char *
localized_pattern (const char *english_pattern, nl_item nl_index,
                   bool posixly_correct)
{
  const char *translated_pattern;

  /* We prefer to get the patterns from a PO file.  It would be possible to
     always use nl_langinfo (YESEXPR) instead of _("^[yY]"), and
     nl_langinfo (NOEXPR) instead of _("^[nN]"), if we could assume that the
     system's locale support is good.  But this is not the case e.g. on Cygwin.
     The localizations of gnulib.pot are of better quality in general.
     Also, if we use locale info from non-free systems that don't have a
     'localedef' command, we deprive the users of the freedom to localize
     this pattern for their preferred language.
     But some programs, such as 'cp', 'mv', 'rm', 'find', 'xargs', are
     specified by POSIX to use nl_langinfo (YESEXPR).  We implement this
     behaviour if POSIXLY_CORRECT is set, for the sake of these programs.  */

  /* If the user wants strict POSIX compliance, use nl_langinfo.  */
  if (posixly_correct)
    {
      translated_pattern = nl_langinfo (nl_index);
      /* Check against a broken system return value.  */
      if (translated_pattern != NULL && translated_pattern[0] != '\0')
        return translated_pattern;
   }

  /* Look in the gnulib message catalog.  */
  translated_pattern = _(english_pattern);
  if (translated_pattern == english_pattern)
    {
      /* The gnulib message catalog provides no translation.
         Try the system's message catalog.  */
      translated_pattern = nl_langinfo (nl_index);
      /* Check against a broken system return value.  */
      if (translated_pattern != NULL && translated_pattern[0] != '\0')
        return translated_pattern;
      /* Fall back to English.  */
      translated_pattern = english_pattern;
    }
  return translated_pattern;
}
# else
#  define localized_pattern(english_pattern,nl_index,posixly_correct) \
     _(english_pattern)
# endif

static int
try (const char *response, const char *pattern, char **lastp, regex_t *re)
{
  if (*lastp == NULL || strcmp (pattern, *lastp) != 0)
    {
      char *safe_pattern;

      /* The pattern has changed.  */
      if (*lastp != NULL)
        {
          /* Free the old compiled pattern.  */
          regfree (re);
          free (*lastp);
          *lastp = NULL;
        }
      /* Put the PATTERN into safe memory before calling regcomp.
         (regcomp may call nl_langinfo, overwriting PATTERN's storage.  */
      safe_pattern = strdup (pattern);
      if (safe_pattern == NULL)
        return -1;
      /* Compile the pattern and cache it for future runs.  */
      if (regcomp (re, safe_pattern, REG_EXTENDED) != 0)
        {
          free (safe_pattern);
          return -1;
        }
      *lastp = safe_pattern;
    }

  /* See if the regular expression matches RESPONSE.  */
  return regexec (re, response, 0, NULL, 0) == 0;
}
#endif


int
rpmatch (const char *response)
{
#if ENABLE_NLS
  /* Match against one of the response patterns, compiling the pattern
     first if necessary.  */

  /* We cache the response patterns and compiled regexps here.  */
  static char *last_yesexpr, *last_noexpr;
  static regex_t cached_yesre, cached_nore;

# if HAVE_LANGINFO_YESEXPR
  bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
# endif

  const char *yesexpr, *noexpr;
  int result;

  /* TRANSLATORS: A regular expression testing for an affirmative answer
     (english: "yes").  Testing the first character may be sufficient.
     Take care to consider upper and lower case.
     To enquire the regular expression that your system uses for this
     purpose, you can use the command
       locale -k LC_MESSAGES | grep '^yesexpr='  */
  yesexpr = localized_pattern (N_("^[yY]"), YESEXPR, posixly_correct);
  result = try (response, yesexpr, &last_yesexpr, &cached_yesre);
  if (result < 0)
    return -1;
  if (result)
    return 1;

  /* TRANSLATORS: A regular expression testing for a negative answer
     (english: "no").  Testing the first character may be sufficient.
     Take care to consider upper and lower case.
     To enquire the regular expression that your system uses for this
     purpose, you can use the command
       locale -k LC_MESSAGES | grep '^noexpr='  */
  noexpr = localized_pattern (N_("^[nN]"), NOEXPR, posixly_correct);
  result = try (response, noexpr, &last_noexpr, &cached_nore);
  if (result < 0)
    return -1;
  if (result)
    return 0;

  return -1;
#else
  /* Test against "^[yY]" and "^[nN]", hardcoded to avoid requiring regex */
  return (*response == 'y' || *response == 'Y' ? 1
          : *response == 'n' || *response == 'N' ? 0 : -1);
#endif
}
