xref: /netbsd-src/games/trek/getpar.c (revision da121b333149705fd908f272187095dff6b9353c)
1*da121b33Sdholland /*	$NetBSD: getpar.c,v 1.18 2009/08/12 08:54:54 dholland Exp $	*/
2887dd216Scgd 
361f28255Scgd /*
4887dd216Scgd  * Copyright (c) 1980, 1993
5887dd216Scgd  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
15e5aeb4eaSagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
32ef383c95Schristos #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
34887dd216Scgd #if 0
35887dd216Scgd static char sccsid[] = "@(#)getpar.c	8.1 (Berkeley) 5/31/93";
36887dd216Scgd #else
37*da121b33Sdholland __RCSID("$NetBSD: getpar.c,v 1.18 2009/08/12 08:54:54 dholland Exp $");
38887dd216Scgd #endif
3961f28255Scgd #endif /* not lint */
4061f28255Scgd 
4161f28255Scgd #include <stdio.h>
4232330650Smatt #include <stdlib.h>
43ef383c95Schristos #include <string.h>
4461f28255Scgd #include "getpar.h"
45ef383c95Schristos #include "trek.h"
46ef383c95Schristos 
47cb5fd834Sjsm static int testterm(void);
4861f28255Scgd 
4961f28255Scgd /**
5061f28255Scgd  **	get integer parameter
5161f28255Scgd  **/
5261f28255Scgd 
53ef383c95Schristos int
getintpar(const char * s)54bf0917b6Sdholland getintpar(const char *s)
5561f28255Scgd {
56ef383c95Schristos 	int	i;
5761f28255Scgd 	int		n;
5861f28255Scgd 
5950b862e2Sdholland 	while (1) {
6061f28255Scgd 		if (testnl() && s)
6161f28255Scgd 			printf("%s: ", s);
6261f28255Scgd 		i = scanf("%d", &n);
6361f28255Scgd 		if (i < 0)
6461f28255Scgd 			exit(1);
6561f28255Scgd 		if (i > 0 && testterm())
6661f28255Scgd 			return (n);
6761f28255Scgd 		printf("invalid input; please enter an integer\n");
6861f28255Scgd 		skiptonl(0);
6961f28255Scgd 	}
7061f28255Scgd }
7161f28255Scgd 
7261f28255Scgd /**
7361f28255Scgd  **	get floating parameter
7461f28255Scgd  **/
7561f28255Scgd 
76bf0917b6Sdholland double
getfltpar(const char * s)77bf0917b6Sdholland getfltpar(const char *s)
7861f28255Scgd {
79ef383c95Schristos 	int		i;
8061f28255Scgd 	double			d;
8161f28255Scgd 
8250b862e2Sdholland 	while (1) {
8361f28255Scgd 		if (testnl() && s)
8461f28255Scgd 			printf("%s: ", s);
8561f28255Scgd 		i = scanf("%lf", &d);
8661f28255Scgd 		if (i < 0)
8761f28255Scgd 			exit(1);
8861f28255Scgd 		if (i > 0 && testterm())
8961f28255Scgd 			return (d);
9061f28255Scgd 		printf("invalid input; please enter a double\n");
9161f28255Scgd 		skiptonl(0);
9261f28255Scgd 	}
9361f28255Scgd }
9461f28255Scgd 
9561f28255Scgd /**
9661f28255Scgd  **	get yes/no parameter
9761f28255Scgd  **/
9861f28255Scgd 
99*da121b33Sdholland static const struct cvntab Yntab[] = {
100d935cf10Scjs 	{ "y",	"es",	(cmdfun)1,	1 },
101ef383c95Schristos 	{ "n",	"o",	(cmdfun)0,	0 },
102ef383c95Schristos 	{ NULL,	NULL,	NULL,		0 }
10361f28255Scgd };
10461f28255Scgd 
105ef383c95Schristos int
getynpar(const char * s)106bf0917b6Sdholland getynpar(const char *s)
10761f28255Scgd {
108b7e11e5cShubertf 	const struct cvntab	*r;
10961f28255Scgd 
11061f28255Scgd 	r = getcodpar(s, Yntab);
111d935cf10Scjs 	return r->value2;
11261f28255Scgd }
11361f28255Scgd 
11461f28255Scgd 
11561f28255Scgd /**
11661f28255Scgd  **	get coded parameter
11761f28255Scgd  **/
11861f28255Scgd 
119bf0917b6Sdholland const struct cvntab *
getcodpar(const char * s,const struct cvntab tab[])120bf0917b6Sdholland getcodpar(const char *s, const struct cvntab tab[])
12161f28255Scgd {
12261f28255Scgd 	char				input[100];
123b7e11e5cShubertf 	const struct cvntab		*r;
12461f28255Scgd 	int				flag;
125b7e11e5cShubertf 	const char			*p, *q;
12661f28255Scgd 	int				c;
12761f28255Scgd 	int				f;
12861f28255Scgd 
12961f28255Scgd 	flag = 0;
13050b862e2Sdholland 	while (1) {
13161f28255Scgd 		flag |= (f = testnl());
13261f28255Scgd 		if (flag)
13361f28255Scgd 			printf("%s: ", s);
13450b862e2Sdholland 		if (f) {
13550b862e2Sdholland 			/* throw out the newline */
136db2522cfSdholland 			getchar();
13750b862e2Sdholland 		}
13861f28255Scgd 		scanf("%*[ \t;]");
139e12c9d54Sitojun 		if ((c = scanf("%99[^ \t;\n]", input)) < 0)
14061f28255Scgd 			exit(1);
14161f28255Scgd 		if (c == 0)
14261f28255Scgd 			continue;
14361f28255Scgd 		flag = 1;
14461f28255Scgd 
14561f28255Scgd 		/* if command list, print four per line */
14650b862e2Sdholland 		if (input[0] == '?' && input[1] == 0) {
14761f28255Scgd 			c = 4;
148869c9375Sdholland 			for (r = tab; r->abbrev; r++) {
149869c9375Sdholland 				strcpy(input, r->abbrev);
150ef383c95Schristos 				strcat(input, r->full);
15161f28255Scgd 				printf("%14.14s", input);
15261f28255Scgd 				if (--c > 0)
15361f28255Scgd 					continue;
15461f28255Scgd 				c = 4;
15561f28255Scgd 				printf("\n");
15661f28255Scgd 			}
15761f28255Scgd 			if (c != 4)
15861f28255Scgd 				printf("\n");
15961f28255Scgd 			continue;
16061f28255Scgd 		}
16161f28255Scgd 
16261f28255Scgd 		/* search for in table */
163869c9375Sdholland 		for (r = tab; r->abbrev; r++) {
16461f28255Scgd 			p = input;
165869c9375Sdholland 			for (q = r->abbrev; *q; q++)
16661f28255Scgd 				if (*p++ != *q)
16761f28255Scgd 					break;
16850b862e2Sdholland 			if (!*q) {
16961f28255Scgd 				for (q = r->full; *p && *q; q++, p++)
17061f28255Scgd 					if (*p != *q)
17161f28255Scgd 						break;
17261f28255Scgd 				if (!*p || !*q)
17361f28255Scgd 					break;
17461f28255Scgd 			}
17561f28255Scgd 		}
17661f28255Scgd 
17761f28255Scgd 		/* check for not found */
178869c9375Sdholland 		if (!r->abbrev) {
17961f28255Scgd 			printf("invalid input; ? for valid inputs\n");
18061f28255Scgd 			skiptonl(0);
18150b862e2Sdholland 		} else
18261f28255Scgd 			return (r);
18361f28255Scgd 	}
18461f28255Scgd }
18561f28255Scgd 
18661f28255Scgd 
18761f28255Scgd /**
18861f28255Scgd  **	get string parameter
18961f28255Scgd  **/
19061f28255Scgd 
191ef383c95Schristos void
getstrpar(const char * s,char * r,int l,const char * t)192bf0917b6Sdholland getstrpar(const char *s, char *r, int l, const char *t)
19361f28255Scgd {
194ef383c95Schristos 	int	i;
19561f28255Scgd 	char		format[20];
196ef383c95Schristos 	int	f;
19761f28255Scgd 
19861f28255Scgd 	if (t == 0)
19961f28255Scgd 		t = " \t\n;";
20096ebfddfSdholland 	(void)snprintf(format, sizeof(format), "%%%d[^%s]", l, t);
20150b862e2Sdholland 	while (1) {
20261f28255Scgd 		if ((f = testnl()) && s)
20361f28255Scgd 			printf("%s: ", s);
20461f28255Scgd 		if (f)
205db2522cfSdholland 			getchar();
20661f28255Scgd 		scanf("%*[\t ;]");
20761f28255Scgd 		i = scanf(format, r);
20861f28255Scgd 		if (i < 0)
20961f28255Scgd 			exit(1);
21061f28255Scgd 		if (i != 0)
21161f28255Scgd 			return;
21261f28255Scgd 	}
21361f28255Scgd }
21461f28255Scgd 
21561f28255Scgd 
21661f28255Scgd /**
21761f28255Scgd  **	test if newline is next valid character
21861f28255Scgd  **/
21961f28255Scgd 
220ef383c95Schristos int
testnl(void)221bf0917b6Sdholland testnl(void)
22261f28255Scgd {
223db2522cfSdholland 	int c;
22461f28255Scgd 
225db2522cfSdholland 	while ((c = getchar()) != '\n') {
226db2522cfSdholland 		if (c == EOF) {
227db2522cfSdholland 			exit(1);
228db2522cfSdholland 		}
22961f28255Scgd 		if ((c >= '0' && c <= '9') || c == '.' || c == '!' ||
23061f28255Scgd 		    (c >= 'A' && c <= 'Z') ||
23150b862e2Sdholland 		    (c >= 'a' && c <= 'z') || c == '-') {
23261f28255Scgd 			ungetc(c, stdin);
23361f28255Scgd 			return(0);
23461f28255Scgd 		}
235db2522cfSdholland 	}
23661f28255Scgd 	ungetc(c, stdin);
23761f28255Scgd 	return (1);
23861f28255Scgd }
23961f28255Scgd 
24061f28255Scgd 
24161f28255Scgd /**
24261f28255Scgd  **	scan for newline
24361f28255Scgd  **/
24461f28255Scgd 
245ef383c95Schristos void
skiptonl(int c)246bf0917b6Sdholland skiptonl(int c)
24761f28255Scgd {
248db2522cfSdholland 	while (c != '\n') {
249db2522cfSdholland 		c = getchar();
250db2522cfSdholland 		if (c == EOF) {
251db2522cfSdholland 			exit(1);
252db2522cfSdholland 		}
253db2522cfSdholland 	}
25461f28255Scgd 	ungetc('\n', stdin);
25561f28255Scgd 	return;
25661f28255Scgd }
25761f28255Scgd 
25861f28255Scgd 
25961f28255Scgd /**
26061f28255Scgd  **	test for valid terminator
26161f28255Scgd  **/
26261f28255Scgd 
263ef383c95Schristos static int
testterm(void)264bf0917b6Sdholland testterm(void)
26561f28255Scgd {
266db2522cfSdholland 	int c;
26761f28255Scgd 
268db2522cfSdholland 	c = getchar();
269db2522cfSdholland 	if (c == EOF) {
270db2522cfSdholland 		exit(1);
271db2522cfSdholland 	}
27261f28255Scgd 	if (c == '.')
27361f28255Scgd 		return (0);
27461f28255Scgd 	if (c == '\n' || c == ';')
27561f28255Scgd 		ungetc(c, stdin);
27661f28255Scgd 	return (1);
27761f28255Scgd }
27861f28255Scgd 
27961f28255Scgd 
28061f28255Scgd /*
281c640510dSwiz **  TEST FOR SPECIFIED DELIMITER
28261f28255Scgd **
28361f28255Scgd **	The standard input is scanned for the parameter.  If found,
28461f28255Scgd **	it is thrown away and non-zero is returned.  If not found,
28561f28255Scgd **	zero is returned.
28661f28255Scgd */
28761f28255Scgd 
288ef383c95Schristos int
readdelim(int d)289bf0917b6Sdholland readdelim(int d)
29061f28255Scgd {
291db2522cfSdholland 	int c;
29261f28255Scgd 
293db2522cfSdholland 	while ((c = getchar()) != EOF) {
29461f28255Scgd 		if (c == d)
29561f28255Scgd 			return (1);
29661f28255Scgd 		if (c == ' ')
29761f28255Scgd 			continue;
29861f28255Scgd 		ungetc(c, stdin);
299db2522cfSdholland 		return 0;
30061f28255Scgd 	}
301db2522cfSdholland 	exit(1);
30261f28255Scgd }
303