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