Home | History | Annotate | Line # | Download | only in trek
      1 /*	$NetBSD: getpar.c,v 1.18 2009/08/12 08:54:54 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.18 2009/08/12 08:54:54 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 static 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 			getchar();
    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->abbrev; r++) {
    149 				strcpy(input, r->abbrev);
    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->abbrev; r++) {
    164 			p = input;
    165 			for (q = r->abbrev; *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->abbrev) {
    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)snprintf(format, sizeof(format), "%%%d[^%s]", l, t);
    201 	while (1) {
    202 		if ((f = testnl()) && s)
    203 			printf("%s: ", s);
    204 		if (f)
    205 			getchar();
    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 	int c;
    224 
    225 	while ((c = getchar()) != '\n') {
    226 		if (c == EOF) {
    227 			exit(1);
    228 		}
    229 		if ((c >= '0' && c <= '9') || c == '.' || c == '!' ||
    230 		    (c >= 'A' && c <= 'Z') ||
    231 		    (c >= 'a' && c <= 'z') || c == '-') {
    232 			ungetc(c, stdin);
    233 			return(0);
    234 		}
    235 	}
    236 	ungetc(c, stdin);
    237 	return (1);
    238 }
    239 
    240 
    241 /**
    242  **	scan for newline
    243  **/
    244 
    245 void
    246 skiptonl(int c)
    247 {
    248 	while (c != '\n') {
    249 		c = getchar();
    250 		if (c == EOF) {
    251 			exit(1);
    252 		}
    253 	}
    254 	ungetc('\n', stdin);
    255 	return;
    256 }
    257 
    258 
    259 /**
    260  **	test for valid terminator
    261  **/
    262 
    263 static int
    264 testterm(void)
    265 {
    266 	int c;
    267 
    268 	c = getchar();
    269 	if (c == EOF) {
    270 		exit(1);
    271 	}
    272 	if (c == '.')
    273 		return (0);
    274 	if (c == '\n' || c == ';')
    275 		ungetc(c, stdin);
    276 	return (1);
    277 }
    278 
    279 
    280 /*
    281 **  TEST FOR SPECIFIED DELIMITER
    282 **
    283 **	The standard input is scanned for the parameter.  If found,
    284 **	it is thrown away and non-zero is returned.  If not found,
    285 **	zero is returned.
    286 */
    287 
    288 int
    289 readdelim(int d)
    290 {
    291 	int c;
    292 
    293 	while ((c = getchar()) != EOF) {
    294 		if (c == d)
    295 			return (1);
    296 		if (c == ' ')
    297 			continue;
    298 		ungetc(c, stdin);
    299 		return 0;
    300 	}
    301 	exit(1);
    302 }
    303