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