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