xref: /netbsd-src/games/trek/getpar.c (revision 274254cdae52594c1aa480a736aef78313d15c9c)
1 /*	$NetBSD: getpar.c,v 1.12 2004/01/27 20:30:31 jsm 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.12 2004/01/27 20:30:31 jsm 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(s)
55 	const char	*s;
56 {
57 	int	i;
58 	int		n;
59 
60 	while (1)
61 	{
62 		if (testnl() && s)
63 			printf("%s: ", s);
64 		i = scanf("%d", &n);
65 		if (i < 0)
66 			exit(1);
67 		if (i > 0 && testterm())
68 			return (n);
69 		printf("invalid input; please enter an integer\n");
70 		skiptonl(0);
71 	}
72 }
73 
74 /**
75  **	get floating parameter
76  **/
77 
78 double getfltpar(s)
79 	const char	*s;
80 {
81 	int		i;
82 	double			d;
83 
84 	while (1)
85 	{
86 		if (testnl() && s)
87 			printf("%s: ", s);
88 		i = scanf("%lf", &d);
89 		if (i < 0)
90 			exit(1);
91 		if (i > 0 && testterm())
92 			return (d);
93 		printf("invalid input; please enter a double\n");
94 		skiptonl(0);
95 	}
96 }
97 
98 /**
99  **	get yes/no parameter
100  **/
101 
102 const struct cvntab	Yntab[] =
103 {
104 	{ "y",	"es",	(cmdfun)1,	1 },
105 	{ "n",	"o",	(cmdfun)0,	0 },
106 	{ NULL,	NULL,	NULL,		0 }
107 };
108 
109 int
110 getynpar(s)
111 	const char	*s;
112 {
113 	const struct cvntab	*r;
114 
115 	r = getcodpar(s, Yntab);
116 	return r->value2;
117 }
118 
119 
120 /**
121  **	get coded parameter
122  **/
123 
124 const struct cvntab *getcodpar(s, tab)
125 	const char		*s;
126 	const struct cvntab	tab[];
127 {
128 	char				input[100];
129 	const struct cvntab		*r;
130 	int				flag;
131 	const char			*p, *q;
132 	int				c;
133 	int				f;
134 
135 	flag = 0;
136 	while (1)
137 	{
138 		flag |= (f = testnl());
139 		if (flag)
140 			printf("%s: ", s);
141 		if (f)
142 			cgetc(0);		/* throw out the newline */
143 		scanf("%*[ \t;]");
144 		if ((c = scanf("%99[^ \t;\n]", input)) < 0)
145 			exit(1);
146 		if (c == 0)
147 			continue;
148 		flag = 1;
149 
150 		/* if command list, print four per line */
151 		if (input[0] == '?' && input[1] == 0)
152 		{
153 			c = 4;
154 			for (r = tab; r->abrev; r++)
155 			{
156 				strcpy(input, r->abrev);
157 				strcat(input, r->full);
158 				printf("%14.14s", input);
159 				if (--c > 0)
160 					continue;
161 				c = 4;
162 				printf("\n");
163 			}
164 			if (c != 4)
165 				printf("\n");
166 			continue;
167 		}
168 
169 		/* search for in table */
170 		for (r = tab; r->abrev; r++)
171 		{
172 			p = input;
173 			for (q = r->abrev; *q; q++)
174 				if (*p++ != *q)
175 					break;
176 			if (!*q)
177 			{
178 				for (q = r->full; *p && *q; q++, p++)
179 					if (*p != *q)
180 						break;
181 				if (!*p || !*q)
182 					break;
183 			}
184 		}
185 
186 		/* check for not found */
187 		if (!r->abrev)
188 		{
189 			printf("invalid input; ? for valid inputs\n");
190 			skiptonl(0);
191 		}
192 		else
193 			return (r);
194 	}
195 }
196 
197 
198 /**
199  **	get string parameter
200  **/
201 
202 void
203 getstrpar(s, r, l, t)
204 	const char	*s;
205 	char	*r;
206 	int	l;
207 	const char	*t;
208 {
209 	int	i;
210 	char		format[20];
211 	int	f;
212 
213 	if (t == 0)
214 		t = " \t\n;";
215 	(void)sprintf(format, "%%%d[^%s]", l, t);
216 	while (1)
217 	{
218 		if ((f = testnl()) && s)
219 			printf("%s: ", s);
220 		if (f)
221 			cgetc(0);
222 		scanf("%*[\t ;]");
223 		i = scanf(format, r);
224 		if (i < 0)
225 			exit(1);
226 		if (i != 0)
227 			return;
228 	}
229 }
230 
231 
232 /**
233  **	test if newline is next valid character
234  **/
235 
236 int
237 testnl()
238 {
239 	char		c;
240 
241 	while ((c = cgetc(0)) != '\n')
242 		if ((c >= '0' && c <= '9') || c == '.' || c == '!' ||
243 				(c >= 'A' && c <= 'Z') ||
244 				(c >= 'a' && c <= 'z') || c == '-')
245 		{
246 			ungetc(c, stdin);
247 			return(0);
248 		}
249 	ungetc(c, stdin);
250 	return (1);
251 }
252 
253 
254 /**
255  **	scan for newline
256  **/
257 
258 void
259 skiptonl(c)
260 int	c;
261 {
262 	while (c != '\n')
263 		if (!(c = cgetc(0)))
264 			return;
265 	ungetc('\n', stdin);
266 	return;
267 }
268 
269 
270 /**
271  **	test for valid terminator
272  **/
273 
274 static int
275 testterm()
276 {
277 	char		c;
278 
279 	if (!(c = cgetc(0)))
280 		return (1);
281 	if (c == '.')
282 		return (0);
283 	if (c == '\n' || c == ';')
284 		ungetc(c, stdin);
285 	return (1);
286 }
287 
288 
289 /*
290 **  TEST FOR SPECIFIED DELIMITER
291 **
292 **	The standard input is scanned for the parameter.  If found,
293 **	it is thrown away and non-zero is returned.  If not found,
294 **	zero is returned.
295 */
296 
297 int
298 readdelim(d)
299 char	d;
300 {
301 	char	c;
302 
303 	while ((c = cgetc(0)) != '\0')
304 	{
305 		if (c == d)
306 			return (1);
307 		if (c == ' ')
308 			continue;
309 		ungetc(c, stdin);
310 		break;
311 	}
312 	return (0);
313 }
314