1/* $NetBSD: getopt.c,v 1.1.1.1 2021/04/07 02:43:15 christos Exp $ */ 2/* NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp */ 3 4/* 5 * Copyright (c) 1987, 1993, 1994, 1995 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 names of the copyright holders nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 21 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#if 0 34static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; 35#endif 36 37#include <assert.h> 38#include <errno.h> 39#include <stdio.h> 40#include <string.h> 41 42#define __P(x) x 43#define _DIAGASSERT(x) assert(x) 44 45#ifdef __weak_alias 46__weak_alias(getopt,_getopt); 47#endif 48 49 50int opterr = 1, /* if error message should be printed */ 51 optind = 1, /* index into parent argv vector */ 52 optopt, /* character checked for validity */ 53 optreset; /* reset getopt */ 54char *optarg; /* argument associated with option */ 55 56static char * _progname __P((char *)); 57int getopt_internal __P((int, char * const *, const char *)); 58 59static char * 60_progname(nargv0) 61 char * nargv0; 62{ 63 char * tmp; 64 65 _DIAGASSERT(nargv0 != NULL); 66 67 tmp = strrchr(nargv0, '/'); 68 if (tmp) 69 tmp++; 70 else 71 tmp = nargv0; 72 return(tmp); 73} 74 75#define BADCH (int)'?' 76#define BADARG (int)':' 77#define EMSG "" 78 79/* 80 * getopt -- 81 * Parse argc/argv argument vector. 82 */ 83int 84getopt(nargc, nargv, ostr) 85 int nargc; 86 char * const nargv[]; 87 const char *ostr; 88{ 89 static char *__progname = 0; 90 static char *place = EMSG; /* option letter processing */ 91 char *oli; /* option letter list index */ 92 __progname = __progname?__progname:_progname(*nargv); 93 94 _DIAGASSERT(nargv != NULL); 95 _DIAGASSERT(ostr != NULL); 96 97 if (optreset || !*place) { /* update scanning pointer */ 98 optreset = 0; 99 if (optind >= nargc || *(place = nargv[optind]) != '-') { 100 place = EMSG; 101 return (-1); 102 } 103 if (place[1] && *++place == '-' /* found "--" */ 104 && place[1] == '\0') { 105 ++optind; 106 place = EMSG; 107 return (-1); 108 } 109 } /* option letter okay? */ 110 if ((optopt = (int)*place++) == (int)':' || 111 !(oli = strchr(ostr, optopt))) { 112 /* 113 * if the user didn't specify '-' as an option, 114 * assume it means -1. 115 */ 116 if (optopt == (int)'-') 117 return (-1); 118 if (!*place) 119 ++optind; 120 if (opterr && *ostr != ':') 121 (void)fprintf(stderr, 122 "%s: illegal option -- %c\n", __progname, optopt); 123 return (BADCH); 124 } 125 if (*++oli != ':') { /* don't need argument */ 126 optarg = NULL; 127 if (!*place) 128 ++optind; 129 } 130 else { /* need an argument */ 131 if (*place) /* no white space */ 132 optarg = place; 133 else if (nargc <= ++optind) { /* no arg */ 134 place = EMSG; 135 if (*ostr == ':') 136 return (BADARG); 137 if (opterr) 138 (void)fprintf(stderr, 139 "%s: option requires an argument -- %c\n", 140 __progname, optopt); 141 return (BADCH); 142 } 143 else /* white space */ 144 optarg = nargv[optind]; 145 place = EMSG; 146 ++optind; 147 } 148 return (optopt); /* dump back option letter */ 149} 150 151