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 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #ifndef lint 39 /* from: static char sccsid[] = "@(#)egetopt.c 8.1 (Berkeley) 6/6/93"; */ 40 static char *rcsid = "$Id: egetopt.c,v 1.1.1.1 1995/10/18 08:45:56 deraadt Exp $"; 41 #endif /* not lint */ 42 43 #include <ctype.h> 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <string.h> 47 48 #include "extern.h" 49 50 /* 51 * egetopt: get option letter from argument vector (an extended 52 * version of getopt). 53 * 54 * Non standard additions to the ostr specs are: 55 * 1) '?': immediate value following arg is optional (no white space 56 * between the arg and the value) 57 * 2) '#': +/- followed by a number (with an optional sign but 58 * no white space between the arg and the number). The - may be 59 * combined with other options, but the + cannot. 60 */ 61 62 int eopterr = 1; /* if error message should be printed */ 63 int eoptind = 1; /* index into parent argv vector */ 64 int eoptopt; /* character checked for validity */ 65 char *eoptarg; /* argument associated with option */ 66 67 #define BADCH (int)'?' 68 #define EMSG "" 69 70 int 71 egetopt(nargc, nargv, ostr) 72 int nargc; 73 char * const *nargv; 74 const char *ostr; 75 { 76 static char *place = EMSG; /* option letter processing */ 77 register char *oli; /* option letter list index */ 78 static int delim; /* which option delimeter */ 79 register char *p; 80 static char savec = '\0'; 81 82 if (savec != '\0') { 83 *place = savec; 84 savec = '\0'; 85 } 86 87 if (!*place) { 88 /* 89 * update scanning pointer 90 */ 91 if ((eoptind >= nargc) || 92 ((*(place = nargv[eoptind]) != '-') && (*place != '+'))) { 93 place = EMSG; 94 return (EOF); 95 } 96 97 delim = (int)*place; 98 if (place[1] && *++place == '-' && !place[1]) { 99 /* 100 * found "--" 101 */ 102 ++eoptind; 103 place = EMSG; 104 return (EOF); 105 } 106 } 107 108 /* 109 * check option letter 110 */ 111 if ((eoptopt = (int)*place++) == (int)':' || (eoptopt == (int)'?') || 112 !(oli = strchr(ostr, eoptopt))) { 113 /* 114 * if the user didn't specify '-' as an option, 115 * assume it means EOF when by itself. 116 */ 117 if ((eoptopt == (int)'-') && !*place) 118 return (EOF); 119 if (strchr(ostr, '#') && (isdigit(eoptopt) || 120 (((eoptopt == (int)'-') || (eoptopt == (int)'+')) && 121 isdigit(*place)))) { 122 /* 123 * # option: +/- with a number is ok 124 */ 125 for (p = place; *p != '\0'; ++p) { 126 if (!isdigit(*p)) 127 break; 128 } 129 eoptarg = place-1; 130 131 if (*p == '\0') { 132 place = EMSG; 133 ++eoptind; 134 } else { 135 place = p; 136 savec = *p; 137 *place = '\0'; 138 } 139 return (delim); 140 } 141 142 if (!*place) 143 ++eoptind; 144 if (eopterr) { 145 if (!(p = strrchr(*nargv, '/'))) 146 p = *nargv; 147 else 148 ++p; 149 (void)fprintf(stderr, "%s: illegal option -- %c\n", 150 p, eoptopt); 151 } 152 return (BADCH); 153 } 154 if (delim == (int)'+') { 155 /* 156 * '+' is only allowed with numbers 157 */ 158 if (!*place) 159 ++eoptind; 160 if (eopterr) { 161 if (!(p = strrchr(*nargv, '/'))) 162 p = *nargv; 163 else 164 ++p; 165 (void)fprintf(stderr, 166 "%s: illegal '+' delimiter with option -- %c\n", 167 p, eoptopt); 168 } 169 return (BADCH); 170 } 171 ++oli; 172 if ((*oli != ':') && (*oli != '?')) { 173 /* 174 * don't need argument 175 */ 176 eoptarg = NULL; 177 if (!*place) 178 ++eoptind; 179 return (eoptopt); 180 } 181 182 if (*place) { 183 /* 184 * no white space 185 */ 186 eoptarg = place; 187 } else if (*oli == '?') { 188 /* 189 * no arg, but NOT required 190 */ 191 eoptarg = NULL; 192 } else if (nargc <= ++eoptind) { 193 /* 194 * no arg, but IS required 195 */ 196 place = EMSG; 197 if (eopterr) { 198 if (!(p = strrchr(*nargv, '/'))) 199 p = *nargv; 200 else 201 ++p; 202 (void)fprintf(stderr, 203 "%s: option requires an argument -- %c\n", p, 204 eoptopt); 205 } 206 return (BADCH); 207 } else { 208 /* 209 * arg has white space 210 */ 211 eoptarg = nargv[eoptind]; 212 } 213 place = EMSG; 214 ++eoptind; 215 return (eoptopt); 216 } 217