dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / common / util / getresponse.c
bloba6804671bbc284233633a76b3adb646642b9bf09
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <regex.h>
30 #include <locale.h>
31 #include <langinfo.h>
32 #include <limits.h>
33 #include <errno.h>
34 #include "getresponse.h"
36 /* defaults - C locale values for yesexpr/noexpr (LC_MESSAGES) */
37 #define DEFAULT_YESEXPR "^[yY]"
38 #define DEFAULT_NOEXPR "^[nN]"
40 #define FREE_MEM \
41 free(yesexpr); \
42 free(noexpr)
44 #define SET_DEFAULT_STRS \
45 yesexpr = DEFAULT_YESEXPR; \
46 noexpr = DEFAULT_NOEXPR;
48 /* for regcomp()/regexec() yesexpr and noexpr */
49 static regex_t preg_yes, preg_no;
52 * This function compiles a regular expression that is used to match an
53 * affirmative response from the user, and also assigns the strings used
54 * in the prompts that request affirmative or negative responses. The
55 * locale's values for YESEXPR, NOEXPR, YESSTR and NOSTR are used.
57 * If there are any problems using the locale's YESEXPR, NOEXPR, YESSTR or NOSTR
58 * values, default values of YESEXPR, YESSTR and NOSTR will be used
59 * as a fallback. The default values are the same as the C locale values.
61 int
62 init_yes(void)
64 int fallback = 0;
65 char *yesexpr;
66 char *noexpr;
68 yesexpr = strdup(nl_langinfo(YESEXPR));
69 noexpr = strdup(nl_langinfo(NOEXPR));
71 if (yesexpr == NULL || noexpr == NULL) {
72 FREE_MEM;
73 errno = ENOMEM;
74 return (-1);
77 /* if problem with locale strings, use default values */
78 if (*yesexpr == '\0' || *noexpr == '\0') {
79 FREE_MEM;
80 SET_DEFAULT_STRS;
81 fallback = 1;
83 /* Compile the yes and no expressions */
84 while (regcomp(&preg_yes, yesexpr, REG_EXTENDED | REG_NOSUB) != 0 ||
85 regcomp(&preg_no, noexpr, REG_EXTENDED | REG_NOSUB) != 0) {
86 if (fallback == 1) {
87 /* The fallback yesexpr failed, so exit */
88 errno = EINVAL;
89 return (-1);
91 /* The locale's yesexpr or noexpr failed so use fallback */
92 FREE_MEM;
93 SET_DEFAULT_STRS;
94 fallback = 1;
96 return (0);
99 static int
100 yes_no(int (*func)(char *))
102 int i, b;
103 char ans[LINE_MAX + 1];
105 /* Get user's answer */
106 i = 0;
107 for (;;) {
108 b = getchar();
109 if (b == '\n' || b == '\0' || b == EOF)
110 break;
111 if (i < LINE_MAX)
112 ans[i] = b;
113 i++;
115 if (i >= LINE_MAX)
116 ans[LINE_MAX] = '\0';
117 else
118 ans[i] = '\0';
120 return (func(ans));
123 static int
124 yes_no_check(char *ans, regex_t *reg1, regex_t *reg2)
126 if (regexec(reg1, ans, 0, NULL, 0) == 0) {
127 if (regexec(reg2, ans, 0, NULL, 0) == 0) {
128 /* Both Expressions Match (reg2 conservative) */
129 return (0);
131 /* Match */
132 return (1);
134 return (0);
138 * yes_check() returns 1 if the input string is matched by yesexpr and is
139 * not matched by noexpr; otherwise yes_check() returns 0.
142 yes_check(char *ans)
144 return (yes_no_check(ans, &preg_yes, &preg_no));
148 * no_check() returns 1 if the input string is matched by noexpr and is
149 * not matched by yesexpr; otherwise no_check() returns 0.
152 no_check(char *ans)
154 return (yes_no_check(ans, &preg_no, &preg_yes));
158 yes(void)
160 return (yes_no(yes_check));
164 no(void)
166 return (yes_no(no_check));