getopt.c revision 165903
1203288Srnoland/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */ 2203288Srnoland 3203288Srnoland/* 4203288Srnoland * Copyright (c) 1987, 1993, 1994 5203288Srnoland * The Regents of the University of California. All rights reserved. 6203288Srnoland * 7203288Srnoland * Redistribution and use in source and binary forms, with or without 8203288Srnoland * modification, are permitted provided that the following conditions 9203288Srnoland * are met: 10203288Srnoland * 1. Redistributions of source code must retain the above copyright 11203288Srnoland * notice, this list of conditions and the following disclaimer. 12203288Srnoland * 2. Redistributions in binary form must reproduce the above copyright 13203288Srnoland * notice, this list of conditions and the following disclaimer in the 14203288Srnoland * documentation and/or other materials provided with the distribution. 15203288Srnoland * 4. Neither the name of the University nor the names of its contributors 16203288Srnoland * may be used to endorse or promote products derived from this software 17203288Srnoland * without specific prior written permission. 18203288Srnoland * 19203288Srnoland * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20203288Srnoland * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21203288Srnoland * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22203288Srnoland * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23203288Srnoland * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24203288Srnoland * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25203288Srnoland * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26203288Srnoland * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27203288Srnoland * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28203288Srnoland * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29203288Srnoland * SUCH DAMAGE. 30203288Srnoland */ 31203288Srnoland 32203288Srnoland#if defined(LIBC_SCCS) && !defined(lint) 33203288Srnolandstatic char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; 34203288Srnoland#endif /* LIBC_SCCS and not lint */ 35203288Srnoland#include <sys/cdefs.h> 36203288Srnoland__FBSDID("$FreeBSD: head/lib/libc/stdlib/getopt.c 165903 2007-01-09 00:28:16Z imp $"); 37203288Srnoland 38203288Srnoland#include "namespace.h" 39203288Srnoland#include <stdio.h> 40203288Srnoland#include <stdlib.h> 41203288Srnoland#include <string.h> 42203288Srnoland#include <unistd.h> 43203288Srnoland#include "un-namespace.h" 44203288Srnoland 45203288Srnoland#include "libc_private.h" 46203288Srnoland 47203288Srnolandint opterr = 1, /* if error message should be printed */ 48203288Srnoland optind = 1, /* index into parent argv vector */ 49203288Srnoland optopt, /* character checked for validity */ 50203288Srnoland optreset; /* reset getopt */ 51203288Srnolandchar *optarg; /* argument associated with option */ 52203288Srnoland 53203288Srnoland#define BADCH (int)'?' 54203288Srnoland#define BADARG (int)':' 55203288Srnoland#define EMSG "" 56203288Srnoland 57203288Srnoland/* 58203288Srnoland * getopt -- 59203288Srnoland * Parse argc/argv argument vector. 60203288Srnoland */ 61203288Srnolandint 62203288Srnolandgetopt(nargc, nargv, ostr) 63203288Srnoland int nargc; 64203288Srnoland char * const nargv[]; 65203288Srnoland const char *ostr; 66203288Srnoland{ 67203288Srnoland static char *place = EMSG; /* option letter processing */ 68203288Srnoland char *oli; /* option letter list index */ 69203288Srnoland 70203288Srnoland if (optreset || *place == 0) { /* update scanning pointer */ 71203288Srnoland optreset = 0; 72203288Srnoland place = nargv[optind]; 73203288Srnoland if (optind >= nargc || *place++ != '-') { 74203288Srnoland /* Argument is absent or is not an option */ 75203288Srnoland place = EMSG; 76203288Srnoland return (-1); 77203288Srnoland } 78203288Srnoland optopt = *place++; 79203288Srnoland if (optopt == '-' && *place == 0) { 80203288Srnoland /* "--" => end of options */ 81203288Srnoland ++optind; 82203288Srnoland place = EMSG; 83203288Srnoland return (-1); 84203288Srnoland } 85203288Srnoland if (optopt == 0) { 86203288Srnoland /* Solitary '-', treat as a '-' option 87203288Srnoland if the program (eg su) is looking for it. */ 88203288Srnoland place = EMSG; 89203288Srnoland if (strchr(ostr, '-') == NULL) 90203288Srnoland return (-1); 91203288Srnoland optopt = '-'; 92203288Srnoland } 93203288Srnoland } else 94203288Srnoland optopt = *place++; 95203288Srnoland 96203288Srnoland /* See if option letter is one the caller wanted... */ 97203288Srnoland if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) { 98203288Srnoland if (*place == 0) 99203288Srnoland ++optind; 100203288Srnoland if (opterr && *ostr != ':') 101203288Srnoland (void)fprintf(stderr, 102203288Srnoland "%s: illegal option -- %c\n", _getprogname(), 103203288Srnoland optopt); 104203288Srnoland return (BADCH); 105203288Srnoland } 106203288Srnoland 107203288Srnoland /* Does this option need an argument? */ 108203288Srnoland if (oli[1] != ':') { 109203288Srnoland /* don't need argument */ 110203288Srnoland optarg = NULL; 111203288Srnoland if (*place == 0) 112203288Srnoland ++optind; 113203288Srnoland } else { 114203288Srnoland /* Option-argument is either the rest of this argument or the 115203288Srnoland entire next argument. */ 116203288Srnoland if (*place) 117203288Srnoland optarg = place; 118203288Srnoland else if (nargc > ++optind) 119203288Srnoland optarg = nargv[optind]; 120203288Srnoland else { 121203288Srnoland /* option-argument absent */ 122203288Srnoland place = EMSG; 123203288Srnoland if (*ostr == ':') 124203288Srnoland return (BADARG); 125203288Srnoland if (opterr) 126203288Srnoland (void)fprintf(stderr, 127203288Srnoland "%s: option requires an argument -- %c\n", 128203288Srnoland _getprogname(), optopt); 129203288Srnoland return (BADCH); 130203288Srnoland } 131203288Srnoland place = EMSG; 132203288Srnoland ++optind; 133203288Srnoland } 134203288Srnoland return (optopt); /* return option letter */ 135203288Srnoland} 136203288Srnoland