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 * $DragonFly: src/games/trek/getpar.c,v 1.3 2006/09/07 21:19:44 pavalos Exp $ 32 */ 33 34 #include "getpar.h" 35 #include "trek.h" 36 37 static bool testterm(void); 38 39 /** 40 ** get integer parameter 41 **/ 42 43 int 44 getintpar(const char *s) 45 { 46 int i; 47 int n; 48 49 while (1) { 50 if (testnl() && s) 51 printf("%s: ", s); 52 i = scanf("%d", &n); 53 if (i < 0) 54 exit(1); 55 if (i > 0 && testterm()) 56 return (n); 57 printf("invalid input; please enter an integer\n"); 58 skiptonl(0); 59 } 60 } 61 62 /** 63 ** get floating parameter 64 **/ 65 66 double 67 getfltpar(const char *s) 68 { 69 int i; 70 double d; 71 72 while (1) { 73 if (testnl() && s) 74 printf("%s: ", s); 75 i = scanf("%lf", &d); 76 if (i < 0) 77 exit(1); 78 if (i > 0 && testterm()) 79 return (d); 80 printf("invalid input; please enter a double\n"); 81 skiptonl(0); 82 } 83 } 84 85 /** 86 ** get yes/no parameter 87 **/ 88 89 struct cvntab Yntab[] = { 90 { "y", "es", (cmdfun)1, 0 }, 91 { "n", "o", (cmdfun)0, 0 }, 92 { NULL, NULL, NULL, 0 } 93 }; 94 95 long 96 getynpar(const char *s) 97 { 98 struct cvntab *r; 99 100 r = getcodpar(s, Yntab); 101 return ((long) r->value); 102 } 103 104 105 /** 106 ** get coded parameter 107 **/ 108 109 struct cvntab * 110 getcodpar(const char *s, struct cvntab tab[]) 111 { 112 char input[100]; 113 struct cvntab *r; 114 int flag; 115 char *p; 116 const char *q; 117 int c; 118 int f; 119 120 flag = 0; 121 while (1) { 122 flag |= (f = testnl()); 123 if (flag) 124 printf("%s: ", s); 125 if (f) 126 cgetc(0); /* throw out the newline */ 127 scanf("%*[ \t;]"); 128 if ((c = scanf("%[^ \t;\n]", input)) < 0) 129 exit(1); 130 if (c == 0) 131 continue; 132 flag = 1; 133 134 /* if command list, print four per line */ 135 if (input[0] == '?' && input[1] == 0) { 136 c = 4; 137 for (r = tab; r->abrev; r++) { 138 strcpy(input, r->abrev); 139 strcat(input, r->full); 140 printf("%14.14s", input); 141 if (--c > 0) 142 continue; 143 c = 4; 144 printf("\n"); 145 } 146 if (c != 4) 147 printf("\n"); 148 continue; 149 } 150 151 /* search for in table */ 152 for (r = tab; r->abrev; r++) { 153 p = input; 154 for (q = r->abrev; *q; q++) 155 if (*p++ != *q) 156 break; 157 if (!*q) { 158 for (q = r->full; *p && *q; q++, p++) 159 if (*p != *q) 160 break; 161 if (!*p || !*q) 162 break; 163 } 164 } 165 166 /* check for not found */ 167 if (!r->abrev) { 168 printf("invalid input; ? for valid inputs\n"); 169 skiptonl(0); 170 } 171 else 172 return (r); 173 } 174 } 175 176 177 /** 178 ** get string parameter 179 **/ 180 181 void 182 getstrpar(const char *s, char *r, int l, const char *t) 183 { 184 int i; 185 char format[20]; 186 int f; 187 188 if (t == 0) 189 t = " \t\n;"; 190 sprintf(format, "%%%d[^%s]", l, t); 191 while (1) { 192 if ((f = testnl()) && s) 193 printf("%s: ", s); 194 if (f) 195 cgetc(0); 196 scanf("%*[\t ;]"); 197 i = scanf(format, r); 198 if (i < 0) 199 exit(1); 200 if (i != 0) 201 return; 202 } 203 } 204 205 206 /** 207 ** test if newline is next valid character 208 **/ 209 210 bool 211 testnl(void) 212 { 213 char c; 214 215 while ((c = cgetc(0)) != '\n') { 216 if ((c >= '0' && c <= '9') || c == '.' || c == '!' || 217 (c >= 'A' && c <= 'Z') || 218 (c >= 'a' && c <= 'z') || c == '-') { 219 ungetc(c, stdin); 220 return(0); 221 } 222 } 223 ungetc(c, stdin); 224 return (1); 225 } 226 227 228 /** 229 ** scan for newline 230 **/ 231 232 void 233 skiptonl(char c) 234 { 235 while (c != '\n') { 236 if (!(c = cgetc(0))) 237 return; 238 } 239 ungetc('\n', stdin); 240 return; 241 } 242 243 244 /** 245 ** test for valid terminator 246 **/ 247 248 static bool 249 testterm(void) 250 { 251 char c; 252 253 if (!(c = cgetc(0))) 254 return (1); 255 if (c == '.') 256 return (0); 257 if (c == '\n' || c == ';') 258 ungetc(c, stdin); 259 return (1); 260 } 261 262 263 /* 264 ** TEST FOR SPECIFIED DELIMITER 265 ** 266 ** The standard input is scanned for the parameter. If found, 267 ** it is thrown away and non-zero is returned. If not found, 268 ** zero is returned. 269 */ 270 271 bool 272 readdelim(char d) 273 { 274 char c; 275 276 while ((c = cgetc(0))) { 277 if (c == d) 278 return (1); 279 if (c == ' ') 280 continue; 281 ungetc(c, stdin); 282 break; 283 } 284 return (0); 285 } 286