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