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