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