1 /* @(#)getpar.c 8.1 (Berkeley) 5/31/93 */
2 /* $NetBSD: getpar.c,v 1.18 2009/08/12 08:54:54 dholland Exp $ */
3
4 /*
5 * Copyright (c) 1980, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "getpar.h"
37 #include "trek.h"
38
39 static int testterm(void);
40
41 /**
42 ** get integer parameter
43 **/
44
45 int
getintpar(const char * s)46 getintpar(const char *s)
47 {
48 int i;
49 int n;
50
51 while (1) {
52 if (testnl() && s)
53 printf("%s: ", s);
54 i = scanf("%d", &n);
55 if (i < 0)
56 exit(1);
57 if (i > 0 && testterm())
58 return (n);
59 printf("invalid input; please enter an integer\n");
60 skiptonl(0);
61 }
62 }
63
64 /**
65 ** get floating parameter
66 **/
67
68 double
getfltpar(const char * s)69 getfltpar(const char *s)
70 {
71 int i;
72 double d;
73
74 while (1) {
75 if (testnl() && s)
76 printf("%s: ", s);
77 i = scanf("%lf", &d);
78 if (i < 0)
79 exit(1);
80 if (i > 0 && testterm())
81 return (d);
82 printf("invalid input; please enter a double\n");
83 skiptonl(0);
84 }
85 }
86
87 /**
88 ** get yes/no parameter
89 **/
90
91 static const struct cvntab Yntab[] = {
92 { "y", "es", (cmdfun)1, 1 },
93 { "n", "o", (cmdfun)0, 0 },
94 { NULL, NULL, NULL, 0 }
95 };
96
97 int
getynpar(const char * s)98 getynpar(const char *s)
99 {
100 const struct cvntab *r;
101
102 r = getcodpar(s, Yntab);
103 return r->value2;
104 }
105
106
107 /**
108 ** get coded parameter
109 **/
110
111 const struct cvntab *
getcodpar(const char * s,const struct cvntab tab[])112 getcodpar(const char *s, const struct cvntab tab[])
113 {
114 char input[100];
115 const struct cvntab *r;
116 int flag;
117 const char *p, *q;
118 int c;
119 int f;
120
121 flag = 0;
122 while (1) {
123 flag |= (f = testnl());
124 if (flag)
125 printf("%s: ", s);
126 if (f) {
127 /* throw out the newline */
128 getchar();
129 }
130 scanf("%*[ \t;]");
131 if ((c = scanf("%99[^ \t;\n]", input)) < 0)
132 exit(1);
133 if (c == 0)
134 continue;
135 flag = 1;
136
137 /* if command list, print four per line */
138 if (input[0] == '?' && input[1] == 0) {
139 c = 4;
140 for (r = tab; r->abbrev; r++) {
141 strcpy(input, r->abbrev);
142 strcat(input, r->full);
143 printf("%14.14s", input);
144 if (--c > 0)
145 continue;
146 c = 4;
147 printf("\n");
148 }
149 if (c != 4)
150 printf("\n");
151 continue;
152 }
153
154 /* search for in table */
155 for (r = tab; r->abbrev; r++) {
156 p = input;
157 for (q = r->abbrev; *q; q++)
158 if (*p++ != *q)
159 break;
160 if (!*q) {
161 for (q = r->full; *p && *q; q++, p++)
162 if (*p != *q)
163 break;
164 if (!*p || !*q)
165 break;
166 }
167 }
168
169 /* check for not found */
170 if (!r->abbrev) {
171 printf("invalid input; ? for valid inputs\n");
172 skiptonl(0);
173 } else
174 return (r);
175 }
176 }
177
178
179 /**
180 ** get string parameter
181 **/
182
183 void
getstrpar(const char * s,char * r,int l,const char * t)184 getstrpar(const char *s, char *r, int l, const char *t)
185 {
186 int i;
187 char format[20];
188 int f;
189
190 if (t == 0)
191 t = " \t\n;";
192 (void)snprintf(format, sizeof(format), "%%%d[^%s]", l, t);
193 while (1) {
194 if ((f = testnl()) && s)
195 printf("%s: ", s);
196 if (f)
197 getchar();
198 scanf("%*[\t ;]");
199 i = scanf(format, r);
200 if (i < 0)
201 exit(1);
202 if (i != 0)
203 return;
204 }
205 }
206
207
208 /**
209 ** test if newline is next valid character
210 **/
211
212 int
testnl(void)213 testnl(void)
214 {
215 int c;
216
217 while ((c = getchar()) != '\n') {
218 if (c == EOF) {
219 exit(1);
220 }
221 if ((c >= '0' && c <= '9') || c == '.' || c == '!' ||
222 (c >= 'A' && c <= 'Z') ||
223 (c >= 'a' && c <= 'z') || c == '-') {
224 ungetc(c, stdin);
225 return(0);
226 }
227 }
228 ungetc(c, stdin);
229 return (1);
230 }
231
232
233 /**
234 ** scan for newline
235 **/
236
237 void
skiptonl(int c)238 skiptonl(int c)
239 {
240 while (c != '\n') {
241 c = getchar();
242 if (c == EOF) {
243 exit(1);
244 }
245 }
246 ungetc('\n', stdin);
247 return;
248 }
249
250
251 /**
252 ** test for valid terminator
253 **/
254
255 static int
testterm(void)256 testterm(void)
257 {
258 int c;
259
260 c = getchar();
261 if (c == EOF) {
262 exit(1);
263 }
264 if (c == '.')
265 return (0);
266 if (c == '\n' || c == ';')
267 ungetc(c, stdin);
268 return (1);
269 }
270
271
272 /*
273 ** TEST FOR SPECIFIED DELIMITER
274 **
275 ** The standard input is scanned for the parameter. If found,
276 ** it is thrown away and non-zero is returned. If not found,
277 ** zero is returned.
278 */
279
280 int
readdelim(int d)281 readdelim(int d)
282 {
283 int c;
284
285 while ((c = getchar()) != EOF) {
286 if (c == d)
287 return (1);
288 if (c == ' ')
289 continue;
290 ungetc(c, stdin);
291 return 0;
292 }
293 exit(1);
294 }
295