1 /* Determine whether string value is affirmation or negative response
   2    according to current locale's data.
   3 
   4    Copyright (C) 1996, 1998, 2000, 2002, 2003, 2006 Free Software
   5    Foundation, Inc.
   6 
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 2, or (at your option)
  10    any later version.
  11 
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16 
  17    You should have received a copy of the GNU General Public License
  18    along with this program; if not, write to the Free Software Foundation,
  19    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  20 
  21 #include <config.h>
  22 
  23 #include <stddef.h>
  24 #include <stdlib.h>
  25 
  26 #if ENABLE_NLS
  27 # include <sys/types.h>
  28 # include <limits.h>
  29 # include <regex.h>
  30 # include "gettext.h"
  31 # define _(msgid) gettext (msgid)
  32 
  33 static int
  34 try (const char *response, const char *pattern, const int match,
  35      const int nomatch, const char **lastp, regex_t *re)
  36 {
  37   if (pattern != *lastp)
  38     {
  39       /* The pattern has changed.  */
  40       if (*lastp)
  41         {
  42           /* Free the old compiled pattern.  */
  43           regfree (re);
  44           *lastp = NULL;
  45         }
  46       /* Compile the pattern and cache it for future runs.  */
  47       if (regcomp (re, pattern, REG_EXTENDED) != 0)
  48         return -1;
  49       *lastp = pattern;
  50     }
  51 
  52   /* See if the regular expression matches RESPONSE.  */
  53   return regexec (re, response, 0, NULL, 0) == 0 ? match : nomatch;
  54 }
  55 #endif
  56 
  57 
  58 int
  59 rpmatch (const char *response)
  60 {
  61 #if ENABLE_NLS
  62   /* Match against one of the response patterns, compiling the pattern
  63      first if necessary.  */
  64 
  65   /* We cache the response patterns and compiled regexps here.  */
  66   static const char *yesexpr, *noexpr;
  67   static regex_t yesre, nore;
  68   int result;
  69 
  70   return ((result = try (response, _("^[yY]"), 1, 0,
  71                          &yesexpr, &yesre))
  72           ? result
  73           : try (response, _("^[nN]"), 0, -1, &noexpr, &nore));
  74 #else
  75   /* Test against "^[yY]" and "^[nN]", hardcoded to avoid requiring regex */
  76   return (*response == 'y' || *response == 'Y' ? 1
  77           : *response == 'n' || *response == 'N' ? 0 : -1);
  78 #endif
  79 }