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