1 /*- 2 * Copyright (c) 1991 Keith Muller. 3 * Copyright (c) 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Keith Muller of the University of California, San Diego. 8 * 9 * %sccs.include.redist.c% 10 */ 11 12 #ifndef lint 13 static char sccsid[] = "@(#)egetopt.c 8.1 (Berkeley) 06/06/93"; 14 #endif /* not lint */ 15 16 #include <ctype.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 21 #include "extern.h" 22 23 /* 24 * egetopt: get option letter from argument vector (an extended 25 * version of getopt). 26 * 27 * Non standard additions to the ostr specs are: 28 * 1) '?': immediate value following arg is optional (no white space 29 * between the arg and the value) 30 * 2) '#': +/- followed by a number (with an optional sign but 31 * no white space between the arg and the number). The - may be 32 * combined with other options, but the + cannot. 33 */ 34 35 int eopterr = 1; /* if error message should be printed */ 36 int eoptind = 1; /* index into parent argv vector */ 37 int eoptopt; /* character checked for validity */ 38 char *eoptarg; /* argument associated with option */ 39 40 #define BADCH (int)'?' 41 #define EMSG "" 42 43 int 44 egetopt(nargc, nargv, ostr) 45 int nargc; 46 char * const *nargv; 47 const char *ostr; 48 { 49 static char *place = EMSG; /* option letter processing */ 50 register char *oli; /* option letter list index */ 51 static int delim; /* which option delimeter */ 52 register char *p; 53 static char savec = '\0'; 54 55 if (savec != '\0') { 56 *place = savec; 57 savec = '\0'; 58 } 59 60 if (!*place) { 61 /* 62 * update scanning pointer 63 */ 64 if ((eoptind >= nargc) || 65 ((*(place = nargv[eoptind]) != '-') && (*place != '+'))) { 66 place = EMSG; 67 return (EOF); 68 } 69 70 delim = (int)*place; 71 if (place[1] && *++place == '-' && !place[1]) { 72 /* 73 * found "--" 74 */ 75 ++eoptind; 76 place = EMSG; 77 return (EOF); 78 } 79 } 80 81 /* 82 * check option letter 83 */ 84 if ((eoptopt = (int)*place++) == (int)':' || (eoptopt == (int)'?') || 85 !(oli = strchr(ostr, eoptopt))) { 86 /* 87 * if the user didn't specify '-' as an option, 88 * assume it means EOF when by itself. 89 */ 90 if ((eoptopt == (int)'-') && !*place) 91 return (EOF); 92 if (strchr(ostr, '#') && (isdigit(eoptopt) || 93 (((eoptopt == (int)'-') || (eoptopt == (int)'+')) && 94 isdigit(*place)))) { 95 /* 96 * # option: +/- with a number is ok 97 */ 98 for (p = place; *p != '\0'; ++p) { 99 if (!isdigit(*p)) 100 break; 101 } 102 eoptarg = place-1; 103 104 if (*p == '\0') { 105 place = EMSG; 106 ++eoptind; 107 } else { 108 place = p; 109 savec = *p; 110 *place = '\0'; 111 } 112 return (delim); 113 } 114 115 if (!*place) 116 ++eoptind; 117 if (eopterr) { 118 if (!(p = strrchr(*nargv, '/'))) 119 p = *nargv; 120 else 121 ++p; 122 (void)fprintf(stderr, "%s: illegal option -- %c\n", 123 p, eoptopt); 124 } 125 return (BADCH); 126 } 127 if (delim == (int)'+') { 128 /* 129 * '+' is only allowed with numbers 130 */ 131 if (!*place) 132 ++eoptind; 133 if (eopterr) { 134 if (!(p = strrchr(*nargv, '/'))) 135 p = *nargv; 136 else 137 ++p; 138 (void)fprintf(stderr, 139 "%s: illegal '+' delimiter with option -- %c\n", 140 p, eoptopt); 141 } 142 return (BADCH); 143 } 144 ++oli; 145 if ((*oli != ':') && (*oli != '?')) { 146 /* 147 * don't need argument 148 */ 149 eoptarg = NULL; 150 if (!*place) 151 ++eoptind; 152 return (eoptopt); 153 } 154 155 if (*place) { 156 /* 157 * no white space 158 */ 159 eoptarg = place; 160 } else if (*oli == '?') { 161 /* 162 * no arg, but NOT required 163 */ 164 eoptarg = NULL; 165 } else if (nargc <= ++eoptind) { 166 /* 167 * no arg, but IS required 168 */ 169 place = EMSG; 170 if (eopterr) { 171 if (!(p = strrchr(*nargv, '/'))) 172 p = *nargv; 173 else 174 ++p; 175 (void)fprintf(stderr, 176 "%s: option requires an argument -- %c\n", p, 177 eoptopt); 178 } 179 return (BADCH); 180 } else { 181 /* 182 * arg has white space 183 */ 184 eoptarg = nargv[eoptind]; 185 } 186 place = EMSG; 187 ++eoptind; 188 return (eoptopt); 189 } 190