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