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