1*9d3df31eSSimon J. Gerraty /* $NetBSD: getopt.c,v 1.30 2024/01/19 18:41:38 christos Exp $ */ 2be19d90bSSimon J. Gerraty 33955d011SMarcel Moolenaar /* 43955d011SMarcel Moolenaar * Copyright (c) 1987, 1993, 1994 53955d011SMarcel Moolenaar * The Regents of the University of California. All rights reserved. 63955d011SMarcel Moolenaar * 73955d011SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 83955d011SMarcel Moolenaar * modification, are permitted provided that the following conditions 93955d011SMarcel Moolenaar * are met: 103955d011SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 113955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 123955d011SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 133955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 143955d011SMarcel Moolenaar * documentation and/or other materials provided with the distribution. 15be19d90bSSimon J. Gerraty * 3. Neither the name of the University nor the names of its contributors 163955d011SMarcel Moolenaar * may be used to endorse or promote products derived from this software 173955d011SMarcel Moolenaar * without specific prior written permission. 183955d011SMarcel Moolenaar * 193955d011SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 203955d011SMarcel Moolenaar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 213955d011SMarcel Moolenaar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 223955d011SMarcel Moolenaar * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 233955d011SMarcel Moolenaar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 243955d011SMarcel Moolenaar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 253955d011SMarcel Moolenaar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 263955d011SMarcel Moolenaar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 273955d011SMarcel Moolenaar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 283955d011SMarcel Moolenaar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 293955d011SMarcel Moolenaar * SUCH DAMAGE. 303955d011SMarcel Moolenaar */ 313955d011SMarcel Moolenaar 323955d011SMarcel Moolenaar #ifdef HAVE_CONFIG_H 333955d011SMarcel Moolenaar # include "config.h" 343955d011SMarcel Moolenaar #endif 353955d011SMarcel Moolenaar #if !defined(HAVE_GETOPT) || defined(WANT_GETOPT_LONG) || defined(BROKEN_GETOPT) 36be19d90bSSimon J. Gerraty #include <sys/cdefs.h> 373955d011SMarcel Moolenaar 383955d011SMarcel Moolenaar #include <stdio.h> 393955d011SMarcel Moolenaar #include <stdlib.h> 403955d011SMarcel Moolenaar #include <string.h> 413955d011SMarcel Moolenaar 423955d011SMarcel Moolenaar 433955d011SMarcel Moolenaar #define BADCH (int)'?' 443955d011SMarcel Moolenaar #define BADARG (int)':' 453955d011SMarcel Moolenaar #define EMSG "" 463955d011SMarcel Moolenaar 473955d011SMarcel Moolenaar int opterr = 1, /* if error message should be printed */ 483955d011SMarcel Moolenaar optind = 1, /* index into parent argv vector */ 493955d011SMarcel Moolenaar optopt = BADCH, /* character checked for validity */ 503955d011SMarcel Moolenaar optreset; /* reset getopt */ 513955d011SMarcel Moolenaar char *optarg; /* argument associated with option */ 523955d011SMarcel Moolenaar 533955d011SMarcel Moolenaar /* 543955d011SMarcel Moolenaar * getopt -- 553955d011SMarcel Moolenaar * Parse argc/argv argument vector. 563955d011SMarcel Moolenaar */ 573955d011SMarcel Moolenaar int 58be19d90bSSimon J. Gerraty getopt(int nargc, char * const nargv[], const char *ostr) 593955d011SMarcel Moolenaar { 603955d011SMarcel Moolenaar extern char *__progname; 61be19d90bSSimon J. Gerraty static const char *place = EMSG; /* option letter processing */ 62*9d3df31eSSimon J. Gerraty const char *oli; /* option letter list index */ 633955d011SMarcel Moolenaar 643955d011SMarcel Moolenaar #ifndef BSD4_4 653955d011SMarcel Moolenaar if (!__progname) { 663955d011SMarcel Moolenaar if (__progname = strrchr(nargv[0], '/')) 673955d011SMarcel Moolenaar ++__progname; 683955d011SMarcel Moolenaar else 693955d011SMarcel Moolenaar __progname = nargv[0]; 703955d011SMarcel Moolenaar } 713955d011SMarcel Moolenaar #endif 723955d011SMarcel Moolenaar 73be19d90bSSimon J. Gerraty if (optreset || *place == 0) { /* update scanning pointer */ 743955d011SMarcel Moolenaar optreset = 0; 75be19d90bSSimon J. Gerraty place = nargv[optind]; 76be19d90bSSimon J. Gerraty if (optind >= nargc || *place++ != '-') { 77be19d90bSSimon J. Gerraty /* Argument is absent or is not an option */ 783955d011SMarcel Moolenaar place = EMSG; 793955d011SMarcel Moolenaar return (-1); 803955d011SMarcel Moolenaar } 81be19d90bSSimon J. Gerraty optopt = *place++; 82be19d90bSSimon J. Gerraty if (optopt == '-' && *place == 0) { 83be19d90bSSimon J. Gerraty /* "--" => end of options */ 843955d011SMarcel Moolenaar ++optind; 853955d011SMarcel Moolenaar place = EMSG; 863955d011SMarcel Moolenaar return (-1); 873955d011SMarcel Moolenaar } 88be19d90bSSimon J. Gerraty if (optopt == 0) { 89be19d90bSSimon J. Gerraty /* Solitary '-', treat as a '-' option 90be19d90bSSimon J. Gerraty if the program (eg su) is looking for it. */ 91be19d90bSSimon J. Gerraty place = EMSG; 92be19d90bSSimon J. Gerraty if (strchr(ostr, '-') == NULL) 93be19d90bSSimon J. Gerraty return -1; 94be19d90bSSimon J. Gerraty optopt = '-'; 95be19d90bSSimon J. Gerraty } 96be19d90bSSimon J. Gerraty } else 97be19d90bSSimon J. Gerraty optopt = *place++; 98be19d90bSSimon J. Gerraty 99be19d90bSSimon J. Gerraty /* See if option letter is one the caller wanted... */ 100be19d90bSSimon J. Gerraty if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) { 101be19d90bSSimon J. Gerraty if (*place == 0) 1023955d011SMarcel Moolenaar ++optind; 1033955d011SMarcel Moolenaar if (opterr && *ostr != ':') 1043955d011SMarcel Moolenaar (void)fprintf(stderr, 105be19d90bSSimon J. Gerraty "%s: unknown option -- %c\n", __progname, optopt); 1063955d011SMarcel Moolenaar return (BADCH); 1073955d011SMarcel Moolenaar } 108be19d90bSSimon J. Gerraty 109be19d90bSSimon J. Gerraty /* Does this option need an argument? */ 110be19d90bSSimon J. Gerraty if (oli[1] != ':') { 111be19d90bSSimon J. Gerraty /* don't need argument */ 1123955d011SMarcel Moolenaar optarg = NULL; 113be19d90bSSimon J. Gerraty if (*place == 0) 1143955d011SMarcel Moolenaar ++optind; 115be19d90bSSimon J. Gerraty } else { 116be19d90bSSimon J. Gerraty /* Option-argument is either the rest of this argument or the 117be19d90bSSimon J. Gerraty entire next argument. */ 118be19d90bSSimon J. Gerraty if (*place) 119be19d90bSSimon J. Gerraty optarg = __UNCONST(place); 120be19d90bSSimon J. Gerraty else if (oli[2] == ':') 121be19d90bSSimon J. Gerraty /* 122be19d90bSSimon J. Gerraty * GNU Extension, for optional arguments if the rest of 123be19d90bSSimon J. Gerraty * the argument is empty, we return NULL 124be19d90bSSimon J. Gerraty */ 125be19d90bSSimon J. Gerraty optarg = NULL; 126be19d90bSSimon J. Gerraty else if (nargc > ++optind) 127be19d90bSSimon J. Gerraty optarg = nargv[optind]; 128be19d90bSSimon J. Gerraty else { 129be19d90bSSimon J. Gerraty /* option-argument absent */ 1303955d011SMarcel Moolenaar place = EMSG; 1313955d011SMarcel Moolenaar if (*ostr == ':') 1323955d011SMarcel Moolenaar return (BADARG); 1333955d011SMarcel Moolenaar if (opterr) 1343955d011SMarcel Moolenaar (void)fprintf(stderr, 1353955d011SMarcel Moolenaar "%s: option requires an argument -- %c\n", 1363955d011SMarcel Moolenaar __progname, optopt); 1373955d011SMarcel Moolenaar return (BADCH); 1383955d011SMarcel Moolenaar } 1393955d011SMarcel Moolenaar place = EMSG; 1403955d011SMarcel Moolenaar ++optind; 1413955d011SMarcel Moolenaar } 142be19d90bSSimon J. Gerraty return (optopt); /* return option letter */ 1433955d011SMarcel Moolenaar } 1443955d011SMarcel Moolenaar #endif 1453955d011SMarcel Moolenaar #ifdef MAIN 1463955d011SMarcel Moolenaar #ifndef BSD4_4 1473955d011SMarcel Moolenaar char *__progname; 1483955d011SMarcel Moolenaar #endif 1493955d011SMarcel Moolenaar 1503955d011SMarcel Moolenaar int 1513955d011SMarcel Moolenaar main(argc, argv) 1523955d011SMarcel Moolenaar int argc; 1533955d011SMarcel Moolenaar char *argv[]; 1543955d011SMarcel Moolenaar { 1553955d011SMarcel Moolenaar int c; 1563955d011SMarcel Moolenaar char *opts = argv[1]; 1573955d011SMarcel Moolenaar 1583955d011SMarcel Moolenaar --argc; 1593955d011SMarcel Moolenaar ++argv; 1603955d011SMarcel Moolenaar 1613955d011SMarcel Moolenaar while ((c = getopt(argc, argv, opts)) != EOF) { 1623955d011SMarcel Moolenaar switch (c) { 1633955d011SMarcel Moolenaar case '-': 1643955d011SMarcel Moolenaar if (optarg) 1653955d011SMarcel Moolenaar printf("--%s ", optarg); 1663955d011SMarcel Moolenaar break; 1673955d011SMarcel Moolenaar case '?': 1683955d011SMarcel Moolenaar exit(1); 1693955d011SMarcel Moolenaar break; 1703955d011SMarcel Moolenaar default: 1713955d011SMarcel Moolenaar if (optarg) 1723955d011SMarcel Moolenaar printf("-%c %s ", c, optarg); 1733955d011SMarcel Moolenaar else 1743955d011SMarcel Moolenaar printf("-%c ", c); 1753955d011SMarcel Moolenaar break; 1763955d011SMarcel Moolenaar } 1773955d011SMarcel Moolenaar } 1783955d011SMarcel Moolenaar 1793955d011SMarcel Moolenaar if (optind < argc) { 1803955d011SMarcel Moolenaar printf("-- "); 1813955d011SMarcel Moolenaar for (; optind < argc; ++optind) { 1823955d011SMarcel Moolenaar printf("%s ", argv[optind]); 1833955d011SMarcel Moolenaar } 1843955d011SMarcel Moolenaar } 1853955d011SMarcel Moolenaar printf("\n"); 1863955d011SMarcel Moolenaar exit(0); 1873955d011SMarcel Moolenaar } 1883955d011SMarcel Moolenaar #endif 189