1*1e72d8d2Sderaadt /* Getopt for GNU. 2*1e72d8d2Sderaadt NOTE: getopt is now part of the C library, so if you don't know what 3*1e72d8d2Sderaadt "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu 4*1e72d8d2Sderaadt before changing it! 5*1e72d8d2Sderaadt 6*1e72d8d2Sderaadt Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 7*1e72d8d2Sderaadt Free Software Foundation, Inc. 8*1e72d8d2Sderaadt 9*1e72d8d2Sderaadt This program is free software; you can redistribute it and/or modify it 10*1e72d8d2Sderaadt under the terms of the GNU General Public License as published by the 11*1e72d8d2Sderaadt Free Software Foundation; either version 2, or (at your option) any 12*1e72d8d2Sderaadt later version. 13*1e72d8d2Sderaadt 14*1e72d8d2Sderaadt This program is distributed in the hope that it will be useful, 15*1e72d8d2Sderaadt but WITHOUT ANY WARRANTY; without even the implied warranty of 16*1e72d8d2Sderaadt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17*1e72d8d2Sderaadt GNU General Public License for more details. 18*1e72d8d2Sderaadt 19*1e72d8d2Sderaadt You should have received a copy of the GNU General Public License 20*1e72d8d2Sderaadt along with this program; if not, write to the Free Software 21*1e72d8d2Sderaadt Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 22*1e72d8d2Sderaadt 23*1e72d8d2Sderaadt /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. 24*1e72d8d2Sderaadt Ditto for AIX 3.2 and <stdlib.h>. */ 25*1e72d8d2Sderaadt #ifndef _NO_PROTO 26*1e72d8d2Sderaadt #define _NO_PROTO 27*1e72d8d2Sderaadt #endif 28*1e72d8d2Sderaadt 29*1e72d8d2Sderaadt #ifdef HAVE_CONFIG_H 30*1e72d8d2Sderaadt #if defined (emacs) || defined (CONFIG_BROKETS) 31*1e72d8d2Sderaadt /* We use <config.h> instead of "config.h" so that a compilation 32*1e72d8d2Sderaadt using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h 33*1e72d8d2Sderaadt (which it would do because it found this file in $srcdir). */ 34*1e72d8d2Sderaadt #include <config.h> 35*1e72d8d2Sderaadt #else 36*1e72d8d2Sderaadt #include "config.h" 37*1e72d8d2Sderaadt #endif 38*1e72d8d2Sderaadt #endif 39*1e72d8d2Sderaadt 40*1e72d8d2Sderaadt #ifndef __STDC__ 41*1e72d8d2Sderaadt /* This is a separate conditional since some stdc systems 42*1e72d8d2Sderaadt reject `defined (const)'. */ 43*1e72d8d2Sderaadt #ifndef const 44*1e72d8d2Sderaadt #define const 45*1e72d8d2Sderaadt #endif 46*1e72d8d2Sderaadt #endif 47*1e72d8d2Sderaadt 48*1e72d8d2Sderaadt #include <stdio.h> 49*1e72d8d2Sderaadt 50*1e72d8d2Sderaadt #ifdef HAVE_STRING_H 51*1e72d8d2Sderaadt #include <string.h> 52*1e72d8d2Sderaadt #endif 53*1e72d8d2Sderaadt 54*1e72d8d2Sderaadt /* Comment out all this code if we are using the GNU C Library, and are not 55*1e72d8d2Sderaadt actually compiling the library itself. This code is part of the GNU C 56*1e72d8d2Sderaadt Library, but also included in many other GNU distributions. Compiling 57*1e72d8d2Sderaadt and linking in this code is a waste when using the GNU C library 58*1e72d8d2Sderaadt (especially if it is a shared library). Rather than having every GNU 59*1e72d8d2Sderaadt program understand `configure --with-gnu-libc' and omit the object files, 60*1e72d8d2Sderaadt it is simpler to just do this in the source for each such file. */ 61*1e72d8d2Sderaadt 62*1e72d8d2Sderaadt #if defined (_LIBC) || !defined (__GNU_LIBRARY__) 63*1e72d8d2Sderaadt 64*1e72d8d2Sderaadt 65*1e72d8d2Sderaadt /* This needs to come after some library #include 66*1e72d8d2Sderaadt to get __GNU_LIBRARY__ defined. */ 67*1e72d8d2Sderaadt #ifdef __GNU_LIBRARY__ 68*1e72d8d2Sderaadt /* Don't include stdlib.h for non-GNU C libraries because some of them 69*1e72d8d2Sderaadt contain conflicting prototypes for getopt. */ 70*1e72d8d2Sderaadt #include <stdlib.h> 71*1e72d8d2Sderaadt #endif /* GNU C library. */ 72*1e72d8d2Sderaadt 73*1e72d8d2Sderaadt /* This version of `getopt' appears to the caller like standard Unix `getopt' 74*1e72d8d2Sderaadt but it behaves differently for the user, since it allows the user 75*1e72d8d2Sderaadt to intersperse the options with the other arguments. 76*1e72d8d2Sderaadt 77*1e72d8d2Sderaadt As `getopt' works, it permutes the elements of ARGV so that, 78*1e72d8d2Sderaadt when it is done, all the options precede everything else. Thus 79*1e72d8d2Sderaadt all application programs are extended to handle flexible argument order. 80*1e72d8d2Sderaadt 81*1e72d8d2Sderaadt Setting the environment variable POSIXLY_CORRECT disables permutation. 82*1e72d8d2Sderaadt Then the behavior is completely standard. 83*1e72d8d2Sderaadt 84*1e72d8d2Sderaadt GNU application programs can use a third alternative mode in which 85*1e72d8d2Sderaadt they can distinguish the relative order of options and other arguments. */ 86*1e72d8d2Sderaadt 87*1e72d8d2Sderaadt #ifndef lint 88*1e72d8d2Sderaadt static char rcsid[] = "$CVSid: @(#)getopt.c 1.10 94/09/21 $"; 89*1e72d8d2Sderaadt #endif 90*1e72d8d2Sderaadt 91*1e72d8d2Sderaadt #include "getopt.h" 92*1e72d8d2Sderaadt 93*1e72d8d2Sderaadt /* For communication from `getopt' to the caller. 94*1e72d8d2Sderaadt When `getopt' finds an option that takes an argument, 95*1e72d8d2Sderaadt the argument value is returned here. 96*1e72d8d2Sderaadt Also, when `ordering' is RETURN_IN_ORDER, 97*1e72d8d2Sderaadt each non-option ARGV-element is returned here. */ 98*1e72d8d2Sderaadt 99*1e72d8d2Sderaadt char *optarg = NULL; 100*1e72d8d2Sderaadt 101*1e72d8d2Sderaadt /* Index in ARGV of the next element to be scanned. 102*1e72d8d2Sderaadt This is used for communication to and from the caller 103*1e72d8d2Sderaadt and for communication between successive calls to `getopt'. 104*1e72d8d2Sderaadt 105*1e72d8d2Sderaadt On entry to `getopt', zero means this is the first call; initialize. 106*1e72d8d2Sderaadt 107*1e72d8d2Sderaadt When `getopt' returns EOF, this is the index of the first of the 108*1e72d8d2Sderaadt non-option elements that the caller should itself scan. 109*1e72d8d2Sderaadt 110*1e72d8d2Sderaadt Otherwise, `optind' communicates from one call to the next 111*1e72d8d2Sderaadt how much of ARGV has been scanned so far. */ 112*1e72d8d2Sderaadt 113*1e72d8d2Sderaadt /* XXX 1003.2 says this must be 1 before any call. */ 114*1e72d8d2Sderaadt int optind = 0; 115*1e72d8d2Sderaadt 116*1e72d8d2Sderaadt /* The next char to be scanned in the option-element 117*1e72d8d2Sderaadt in which the last option character we returned was found. 118*1e72d8d2Sderaadt This allows us to pick up the scan where we left off. 119*1e72d8d2Sderaadt 120*1e72d8d2Sderaadt If this is zero, or a null string, it means resume the scan 121*1e72d8d2Sderaadt by advancing to the next ARGV-element. */ 122*1e72d8d2Sderaadt 123*1e72d8d2Sderaadt static char *nextchar; 124*1e72d8d2Sderaadt 125*1e72d8d2Sderaadt /* Callers store zero here to inhibit the error message 126*1e72d8d2Sderaadt for unrecognized options. */ 127*1e72d8d2Sderaadt 128*1e72d8d2Sderaadt int opterr = 1; 129*1e72d8d2Sderaadt 130*1e72d8d2Sderaadt /* Set to an option character which was unrecognized. 131*1e72d8d2Sderaadt This must be initialized on some systems to avoid linking in the 132*1e72d8d2Sderaadt system's own getopt implementation. */ 133*1e72d8d2Sderaadt 134*1e72d8d2Sderaadt int optopt = '?'; 135*1e72d8d2Sderaadt 136*1e72d8d2Sderaadt /* Describe how to deal with options that follow non-option ARGV-elements. 137*1e72d8d2Sderaadt 138*1e72d8d2Sderaadt If the caller did not specify anything, 139*1e72d8d2Sderaadt the default is REQUIRE_ORDER if the environment variable 140*1e72d8d2Sderaadt POSIXLY_CORRECT is defined, PERMUTE otherwise. 141*1e72d8d2Sderaadt 142*1e72d8d2Sderaadt REQUIRE_ORDER means don't recognize them as options; 143*1e72d8d2Sderaadt stop option processing when the first non-option is seen. 144*1e72d8d2Sderaadt This is what Unix does. 145*1e72d8d2Sderaadt This mode of operation is selected by either setting the environment 146*1e72d8d2Sderaadt variable POSIXLY_CORRECT, or using `+' as the first character 147*1e72d8d2Sderaadt of the list of option characters. 148*1e72d8d2Sderaadt 149*1e72d8d2Sderaadt PERMUTE is the default. We permute the contents of ARGV as we scan, 150*1e72d8d2Sderaadt so that eventually all the non-options are at the end. This allows options 151*1e72d8d2Sderaadt to be given in any order, even with programs that were not written to 152*1e72d8d2Sderaadt expect this. 153*1e72d8d2Sderaadt 154*1e72d8d2Sderaadt RETURN_IN_ORDER is an option available to programs that were written 155*1e72d8d2Sderaadt to expect options and other ARGV-elements in any order and that care about 156*1e72d8d2Sderaadt the ordering of the two. We describe each non-option ARGV-element 157*1e72d8d2Sderaadt as if it were the argument of an option with character code 1. 158*1e72d8d2Sderaadt Using `-' as the first character of the list of option characters 159*1e72d8d2Sderaadt selects this mode of operation. 160*1e72d8d2Sderaadt 161*1e72d8d2Sderaadt The special argument `--' forces an end of option-scanning regardless 162*1e72d8d2Sderaadt of the value of `ordering'. In the case of RETURN_IN_ORDER, only 163*1e72d8d2Sderaadt `--' can cause `getopt' to return EOF with `optind' != ARGC. */ 164*1e72d8d2Sderaadt 165*1e72d8d2Sderaadt static enum 166*1e72d8d2Sderaadt { 167*1e72d8d2Sderaadt REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER 168*1e72d8d2Sderaadt } ordering; 169*1e72d8d2Sderaadt 170*1e72d8d2Sderaadt /* Value of POSIXLY_CORRECT environment variable. */ 171*1e72d8d2Sderaadt static char *posixly_correct; 172*1e72d8d2Sderaadt 173*1e72d8d2Sderaadt #ifdef __GNU_LIBRARY__ 174*1e72d8d2Sderaadt /* We want to avoid inclusion of string.h with non-GNU libraries 175*1e72d8d2Sderaadt because there are many ways it can cause trouble. 176*1e72d8d2Sderaadt On some systems, it contains special magic macros that don't work 177*1e72d8d2Sderaadt in GCC. */ 178*1e72d8d2Sderaadt #include <string.h> 179*1e72d8d2Sderaadt #define my_index strchr 180*1e72d8d2Sderaadt #else 181*1e72d8d2Sderaadt 182*1e72d8d2Sderaadt /* Avoid depending on library functions or files 183*1e72d8d2Sderaadt whose names are inconsistent. */ 184*1e72d8d2Sderaadt 185*1e72d8d2Sderaadt char *getenv (); 186*1e72d8d2Sderaadt 187*1e72d8d2Sderaadt static char * 188*1e72d8d2Sderaadt my_index (str, chr) 189*1e72d8d2Sderaadt const char *str; 190*1e72d8d2Sderaadt int chr; 191*1e72d8d2Sderaadt { 192*1e72d8d2Sderaadt while (*str) 193*1e72d8d2Sderaadt { 194*1e72d8d2Sderaadt if (*str == chr) 195*1e72d8d2Sderaadt return (char *) str; 196*1e72d8d2Sderaadt str++; 197*1e72d8d2Sderaadt } 198*1e72d8d2Sderaadt return 0; 199*1e72d8d2Sderaadt } 200*1e72d8d2Sderaadt 201*1e72d8d2Sderaadt /* If using GCC, we can safely declare strlen this way. 202*1e72d8d2Sderaadt If not using GCC, it is ok not to declare it. */ 203*1e72d8d2Sderaadt #ifdef __GNUC__ 204*1e72d8d2Sderaadt /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. 205*1e72d8d2Sderaadt That was relevant to code that was here before. */ 206*1e72d8d2Sderaadt #ifndef __STDC__ 207*1e72d8d2Sderaadt /* gcc with -traditional declares the built-in strlen to return int, 208*1e72d8d2Sderaadt and has done so at least since version 2.4.5. -- rms. */ 209*1e72d8d2Sderaadt extern int strlen (const char *); 210*1e72d8d2Sderaadt #endif /* not __STDC__ */ 211*1e72d8d2Sderaadt #endif /* __GNUC__ */ 212*1e72d8d2Sderaadt 213*1e72d8d2Sderaadt #endif /* not __GNU_LIBRARY__ */ 214*1e72d8d2Sderaadt 215*1e72d8d2Sderaadt /* Handle permutation of arguments. */ 216*1e72d8d2Sderaadt 217*1e72d8d2Sderaadt /* Describe the part of ARGV that contains non-options that have 218*1e72d8d2Sderaadt been skipped. `first_nonopt' is the index in ARGV of the first of them; 219*1e72d8d2Sderaadt `last_nonopt' is the index after the last of them. */ 220*1e72d8d2Sderaadt 221*1e72d8d2Sderaadt static int first_nonopt; 222*1e72d8d2Sderaadt static int last_nonopt; 223*1e72d8d2Sderaadt 224*1e72d8d2Sderaadt /* Exchange two adjacent subsequences of ARGV. 225*1e72d8d2Sderaadt One subsequence is elements [first_nonopt,last_nonopt) 226*1e72d8d2Sderaadt which contains all the non-options that have been skipped so far. 227*1e72d8d2Sderaadt The other is elements [last_nonopt,optind), which contains all 228*1e72d8d2Sderaadt the options processed since those non-options were skipped. 229*1e72d8d2Sderaadt 230*1e72d8d2Sderaadt `first_nonopt' and `last_nonopt' are relocated so that they describe 231*1e72d8d2Sderaadt the new indices of the non-options in ARGV after they are moved. */ 232*1e72d8d2Sderaadt 233*1e72d8d2Sderaadt static void 234*1e72d8d2Sderaadt exchange (argv) 235*1e72d8d2Sderaadt char **argv; 236*1e72d8d2Sderaadt { 237*1e72d8d2Sderaadt int bottom = first_nonopt; 238*1e72d8d2Sderaadt int middle = last_nonopt; 239*1e72d8d2Sderaadt int top = optind; 240*1e72d8d2Sderaadt char *tem; 241*1e72d8d2Sderaadt 242*1e72d8d2Sderaadt /* Exchange the shorter segment with the far end of the longer segment. 243*1e72d8d2Sderaadt That puts the shorter segment into the right place. 244*1e72d8d2Sderaadt It leaves the longer segment in the right place overall, 245*1e72d8d2Sderaadt but it consists of two parts that need to be swapped next. */ 246*1e72d8d2Sderaadt 247*1e72d8d2Sderaadt while (top > middle && middle > bottom) 248*1e72d8d2Sderaadt { 249*1e72d8d2Sderaadt if (top - middle > middle - bottom) 250*1e72d8d2Sderaadt { 251*1e72d8d2Sderaadt /* Bottom segment is the short one. */ 252*1e72d8d2Sderaadt int len = middle - bottom; 253*1e72d8d2Sderaadt register int i; 254*1e72d8d2Sderaadt 255*1e72d8d2Sderaadt /* Swap it with the top part of the top segment. */ 256*1e72d8d2Sderaadt for (i = 0; i < len; i++) 257*1e72d8d2Sderaadt { 258*1e72d8d2Sderaadt tem = argv[bottom + i]; 259*1e72d8d2Sderaadt argv[bottom + i] = argv[top - (middle - bottom) + i]; 260*1e72d8d2Sderaadt argv[top - (middle - bottom) + i] = tem; 261*1e72d8d2Sderaadt } 262*1e72d8d2Sderaadt /* Exclude the moved bottom segment from further swapping. */ 263*1e72d8d2Sderaadt top -= len; 264*1e72d8d2Sderaadt } 265*1e72d8d2Sderaadt else 266*1e72d8d2Sderaadt { 267*1e72d8d2Sderaadt /* Top segment is the short one. */ 268*1e72d8d2Sderaadt int len = top - middle; 269*1e72d8d2Sderaadt register int i; 270*1e72d8d2Sderaadt 271*1e72d8d2Sderaadt /* Swap it with the bottom part of the bottom segment. */ 272*1e72d8d2Sderaadt for (i = 0; i < len; i++) 273*1e72d8d2Sderaadt { 274*1e72d8d2Sderaadt tem = argv[bottom + i]; 275*1e72d8d2Sderaadt argv[bottom + i] = argv[middle + i]; 276*1e72d8d2Sderaadt argv[middle + i] = tem; 277*1e72d8d2Sderaadt } 278*1e72d8d2Sderaadt /* Exclude the moved top segment from further swapping. */ 279*1e72d8d2Sderaadt bottom += len; 280*1e72d8d2Sderaadt } 281*1e72d8d2Sderaadt } 282*1e72d8d2Sderaadt 283*1e72d8d2Sderaadt /* Update records for the slots the non-options now occupy. */ 284*1e72d8d2Sderaadt 285*1e72d8d2Sderaadt first_nonopt += (optind - last_nonopt); 286*1e72d8d2Sderaadt last_nonopt = optind; 287*1e72d8d2Sderaadt } 288*1e72d8d2Sderaadt 289*1e72d8d2Sderaadt /* Initialize the internal data when the first call is made. */ 290*1e72d8d2Sderaadt 291*1e72d8d2Sderaadt static const char * 292*1e72d8d2Sderaadt _getopt_initialize (optstring) 293*1e72d8d2Sderaadt const char *optstring; 294*1e72d8d2Sderaadt { 295*1e72d8d2Sderaadt /* Start processing options with ARGV-element 1 (since ARGV-element 0 296*1e72d8d2Sderaadt is the program name); the sequence of previously skipped 297*1e72d8d2Sderaadt non-option ARGV-elements is empty. */ 298*1e72d8d2Sderaadt 299*1e72d8d2Sderaadt first_nonopt = last_nonopt = optind = 1; 300*1e72d8d2Sderaadt 301*1e72d8d2Sderaadt nextchar = NULL; 302*1e72d8d2Sderaadt 303*1e72d8d2Sderaadt posixly_correct = getenv ("POSIXLY_CORRECT"); 304*1e72d8d2Sderaadt 305*1e72d8d2Sderaadt /* Determine how to handle the ordering of options and nonoptions. */ 306*1e72d8d2Sderaadt 307*1e72d8d2Sderaadt if (optstring[0] == '-') 308*1e72d8d2Sderaadt { 309*1e72d8d2Sderaadt ordering = RETURN_IN_ORDER; 310*1e72d8d2Sderaadt ++optstring; 311*1e72d8d2Sderaadt } 312*1e72d8d2Sderaadt else if (optstring[0] == '+') 313*1e72d8d2Sderaadt { 314*1e72d8d2Sderaadt ordering = REQUIRE_ORDER; 315*1e72d8d2Sderaadt ++optstring; 316*1e72d8d2Sderaadt } 317*1e72d8d2Sderaadt else if (posixly_correct != NULL) 318*1e72d8d2Sderaadt ordering = REQUIRE_ORDER; 319*1e72d8d2Sderaadt else 320*1e72d8d2Sderaadt ordering = PERMUTE; 321*1e72d8d2Sderaadt 322*1e72d8d2Sderaadt return optstring; 323*1e72d8d2Sderaadt } 324*1e72d8d2Sderaadt 325*1e72d8d2Sderaadt /* Scan elements of ARGV (whose length is ARGC) for option characters 326*1e72d8d2Sderaadt given in OPTSTRING. 327*1e72d8d2Sderaadt 328*1e72d8d2Sderaadt If an element of ARGV starts with '-', and is not exactly "-" or "--", 329*1e72d8d2Sderaadt then it is an option element. The characters of this element 330*1e72d8d2Sderaadt (aside from the initial '-') are option characters. If `getopt' 331*1e72d8d2Sderaadt is called repeatedly, it returns successively each of the option characters 332*1e72d8d2Sderaadt from each of the option elements. 333*1e72d8d2Sderaadt 334*1e72d8d2Sderaadt If `getopt' finds another option character, it returns that character, 335*1e72d8d2Sderaadt updating `optind' and `nextchar' so that the next call to `getopt' can 336*1e72d8d2Sderaadt resume the scan with the following option character or ARGV-element. 337*1e72d8d2Sderaadt 338*1e72d8d2Sderaadt If there are no more option characters, `getopt' returns `EOF'. 339*1e72d8d2Sderaadt Then `optind' is the index in ARGV of the first ARGV-element 340*1e72d8d2Sderaadt that is not an option. (The ARGV-elements have been permuted 341*1e72d8d2Sderaadt so that those that are not options now come last.) 342*1e72d8d2Sderaadt 343*1e72d8d2Sderaadt OPTSTRING is a string containing the legitimate option characters. 344*1e72d8d2Sderaadt If an option character is seen that is not listed in OPTSTRING, 345*1e72d8d2Sderaadt return '?' after printing an error message. If you set `opterr' to 346*1e72d8d2Sderaadt zero, the error message is suppressed but we still return '?'. 347*1e72d8d2Sderaadt 348*1e72d8d2Sderaadt If a char in OPTSTRING is followed by a colon, that means it wants an arg, 349*1e72d8d2Sderaadt so the following text in the same ARGV-element, or the text of the following 350*1e72d8d2Sderaadt ARGV-element, is returned in `optarg'. Two colons mean an option that 351*1e72d8d2Sderaadt wants an optional arg; if there is text in the current ARGV-element, 352*1e72d8d2Sderaadt it is returned in `optarg', otherwise `optarg' is set to zero. 353*1e72d8d2Sderaadt 354*1e72d8d2Sderaadt If OPTSTRING starts with `-' or `+', it requests different methods of 355*1e72d8d2Sderaadt handling the non-option ARGV-elements. 356*1e72d8d2Sderaadt See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. 357*1e72d8d2Sderaadt 358*1e72d8d2Sderaadt Long-named options begin with `--' instead of `-'. 359*1e72d8d2Sderaadt Their names may be abbreviated as long as the abbreviation is unique 360*1e72d8d2Sderaadt or is an exact match for some defined option. If they have an 361*1e72d8d2Sderaadt argument, it follows the option name in the same ARGV-element, separated 362*1e72d8d2Sderaadt from the option name by a `=', or else the in next ARGV-element. 363*1e72d8d2Sderaadt When `getopt' finds a long-named option, it returns 0 if that option's 364*1e72d8d2Sderaadt `flag' field is nonzero, the value of the option's `val' field 365*1e72d8d2Sderaadt if the `flag' field is zero. 366*1e72d8d2Sderaadt 367*1e72d8d2Sderaadt The elements of ARGV aren't really const, because we permute them. 368*1e72d8d2Sderaadt But we pretend they're const in the prototype to be compatible 369*1e72d8d2Sderaadt with other systems. 370*1e72d8d2Sderaadt 371*1e72d8d2Sderaadt LONGOPTS is a vector of `struct option' terminated by an 372*1e72d8d2Sderaadt element containing a name which is zero. 373*1e72d8d2Sderaadt 374*1e72d8d2Sderaadt LONGIND returns the index in LONGOPT of the long-named option found. 375*1e72d8d2Sderaadt It is only valid when a long-named option has been found by the most 376*1e72d8d2Sderaadt recent call. 377*1e72d8d2Sderaadt 378*1e72d8d2Sderaadt If LONG_ONLY is nonzero, '-' as well as '--' can introduce 379*1e72d8d2Sderaadt long-named options. */ 380*1e72d8d2Sderaadt 381*1e72d8d2Sderaadt int 382*1e72d8d2Sderaadt _getopt_internal (argc, argv, optstring, longopts, longind, long_only) 383*1e72d8d2Sderaadt int argc; 384*1e72d8d2Sderaadt char *const *argv; 385*1e72d8d2Sderaadt const char *optstring; 386*1e72d8d2Sderaadt const struct option *longopts; 387*1e72d8d2Sderaadt int *longind; 388*1e72d8d2Sderaadt int long_only; 389*1e72d8d2Sderaadt { 390*1e72d8d2Sderaadt optarg = NULL; 391*1e72d8d2Sderaadt 392*1e72d8d2Sderaadt if (optind == 0) 393*1e72d8d2Sderaadt optstring = _getopt_initialize (optstring); 394*1e72d8d2Sderaadt 395*1e72d8d2Sderaadt if (nextchar == NULL || *nextchar == '\0') 396*1e72d8d2Sderaadt { 397*1e72d8d2Sderaadt /* Advance to the next ARGV-element. */ 398*1e72d8d2Sderaadt 399*1e72d8d2Sderaadt if (ordering == PERMUTE) 400*1e72d8d2Sderaadt { 401*1e72d8d2Sderaadt /* If we have just processed some options following some non-options, 402*1e72d8d2Sderaadt exchange them so that the options come first. */ 403*1e72d8d2Sderaadt 404*1e72d8d2Sderaadt if (first_nonopt != last_nonopt && last_nonopt != optind) 405*1e72d8d2Sderaadt exchange ((char **) argv); 406*1e72d8d2Sderaadt else if (last_nonopt != optind) 407*1e72d8d2Sderaadt first_nonopt = optind; 408*1e72d8d2Sderaadt 409*1e72d8d2Sderaadt /* Skip any additional non-options 410*1e72d8d2Sderaadt and extend the range of non-options previously skipped. */ 411*1e72d8d2Sderaadt 412*1e72d8d2Sderaadt while (optind < argc 413*1e72d8d2Sderaadt && (argv[optind][0] != '-' || argv[optind][1] == '\0')) 414*1e72d8d2Sderaadt optind++; 415*1e72d8d2Sderaadt last_nonopt = optind; 416*1e72d8d2Sderaadt } 417*1e72d8d2Sderaadt 418*1e72d8d2Sderaadt /* The special ARGV-element `--' means premature end of options. 419*1e72d8d2Sderaadt Skip it like a null option, 420*1e72d8d2Sderaadt then exchange with previous non-options as if it were an option, 421*1e72d8d2Sderaadt then skip everything else like a non-option. */ 422*1e72d8d2Sderaadt 423*1e72d8d2Sderaadt if (optind != argc && !strcmp (argv[optind], "--")) 424*1e72d8d2Sderaadt { 425*1e72d8d2Sderaadt optind++; 426*1e72d8d2Sderaadt 427*1e72d8d2Sderaadt if (first_nonopt != last_nonopt && last_nonopt != optind) 428*1e72d8d2Sderaadt exchange ((char **) argv); 429*1e72d8d2Sderaadt else if (first_nonopt == last_nonopt) 430*1e72d8d2Sderaadt first_nonopt = optind; 431*1e72d8d2Sderaadt last_nonopt = argc; 432*1e72d8d2Sderaadt 433*1e72d8d2Sderaadt optind = argc; 434*1e72d8d2Sderaadt } 435*1e72d8d2Sderaadt 436*1e72d8d2Sderaadt /* If we have done all the ARGV-elements, stop the scan 437*1e72d8d2Sderaadt and back over any non-options that we skipped and permuted. */ 438*1e72d8d2Sderaadt 439*1e72d8d2Sderaadt if (optind == argc) 440*1e72d8d2Sderaadt { 441*1e72d8d2Sderaadt /* Set the next-arg-index to point at the non-options 442*1e72d8d2Sderaadt that we previously skipped, so the caller will digest them. */ 443*1e72d8d2Sderaadt if (first_nonopt != last_nonopt) 444*1e72d8d2Sderaadt optind = first_nonopt; 445*1e72d8d2Sderaadt return EOF; 446*1e72d8d2Sderaadt } 447*1e72d8d2Sderaadt 448*1e72d8d2Sderaadt /* If we have come to a non-option and did not permute it, 449*1e72d8d2Sderaadt either stop the scan or describe it to the caller and pass it by. */ 450*1e72d8d2Sderaadt 451*1e72d8d2Sderaadt if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) 452*1e72d8d2Sderaadt { 453*1e72d8d2Sderaadt if (ordering == REQUIRE_ORDER) 454*1e72d8d2Sderaadt return EOF; 455*1e72d8d2Sderaadt optarg = argv[optind++]; 456*1e72d8d2Sderaadt return 1; 457*1e72d8d2Sderaadt } 458*1e72d8d2Sderaadt 459*1e72d8d2Sderaadt /* We have found another option-ARGV-element. 460*1e72d8d2Sderaadt Skip the initial punctuation. */ 461*1e72d8d2Sderaadt 462*1e72d8d2Sderaadt nextchar = (argv[optind] + 1 463*1e72d8d2Sderaadt + (longopts != NULL && argv[optind][1] == '-')); 464*1e72d8d2Sderaadt } 465*1e72d8d2Sderaadt 466*1e72d8d2Sderaadt /* Decode the current option-ARGV-element. */ 467*1e72d8d2Sderaadt 468*1e72d8d2Sderaadt /* Check whether the ARGV-element is a long option. 469*1e72d8d2Sderaadt 470*1e72d8d2Sderaadt If long_only and the ARGV-element has the form "-f", where f is 471*1e72d8d2Sderaadt a valid short option, don't consider it an abbreviated form of 472*1e72d8d2Sderaadt a long option that starts with f. Otherwise there would be no 473*1e72d8d2Sderaadt way to give the -f short option. 474*1e72d8d2Sderaadt 475*1e72d8d2Sderaadt On the other hand, if there's a long option "fubar" and 476*1e72d8d2Sderaadt the ARGV-element is "-fu", do consider that an abbreviation of 477*1e72d8d2Sderaadt the long option, just like "--fu", and not "-f" with arg "u". 478*1e72d8d2Sderaadt 479*1e72d8d2Sderaadt This distinction seems to be the most useful approach. */ 480*1e72d8d2Sderaadt 481*1e72d8d2Sderaadt if (longopts != NULL 482*1e72d8d2Sderaadt && (argv[optind][1] == '-' 483*1e72d8d2Sderaadt || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) 484*1e72d8d2Sderaadt { 485*1e72d8d2Sderaadt char *nameend; 486*1e72d8d2Sderaadt const struct option *p; 487*1e72d8d2Sderaadt const struct option *pfound = NULL; 488*1e72d8d2Sderaadt int exact = 0; 489*1e72d8d2Sderaadt int ambig = 0; 490*1e72d8d2Sderaadt int indfound; 491*1e72d8d2Sderaadt int option_index; 492*1e72d8d2Sderaadt 493*1e72d8d2Sderaadt for (nameend = nextchar; *nameend && *nameend != '='; nameend++) 494*1e72d8d2Sderaadt /* Do nothing. */ ; 495*1e72d8d2Sderaadt 496*1e72d8d2Sderaadt /* Test all long options for either exact match 497*1e72d8d2Sderaadt or abbreviated matches. */ 498*1e72d8d2Sderaadt for (p = longopts, option_index = 0; p->name; p++, option_index++) 499*1e72d8d2Sderaadt if (!strncmp (p->name, nextchar, nameend - nextchar)) 500*1e72d8d2Sderaadt { 501*1e72d8d2Sderaadt if (nameend - nextchar == (int) strlen (p->name)) 502*1e72d8d2Sderaadt { 503*1e72d8d2Sderaadt /* Exact match found. */ 504*1e72d8d2Sderaadt pfound = p; 505*1e72d8d2Sderaadt indfound = option_index; 506*1e72d8d2Sderaadt exact = 1; 507*1e72d8d2Sderaadt break; 508*1e72d8d2Sderaadt } 509*1e72d8d2Sderaadt else if (pfound == NULL) 510*1e72d8d2Sderaadt { 511*1e72d8d2Sderaadt /* First nonexact match found. */ 512*1e72d8d2Sderaadt pfound = p; 513*1e72d8d2Sderaadt indfound = option_index; 514*1e72d8d2Sderaadt } 515*1e72d8d2Sderaadt else 516*1e72d8d2Sderaadt /* Second or later nonexact match found. */ 517*1e72d8d2Sderaadt ambig = 1; 518*1e72d8d2Sderaadt } 519*1e72d8d2Sderaadt 520*1e72d8d2Sderaadt if (ambig && !exact) 521*1e72d8d2Sderaadt { 522*1e72d8d2Sderaadt if (opterr) 523*1e72d8d2Sderaadt fprintf (stderr, "%s: option `%s' is ambiguous\n", 524*1e72d8d2Sderaadt argv[0], argv[optind]); 525*1e72d8d2Sderaadt nextchar += strlen (nextchar); 526*1e72d8d2Sderaadt optind++; 527*1e72d8d2Sderaadt return '?'; 528*1e72d8d2Sderaadt } 529*1e72d8d2Sderaadt 530*1e72d8d2Sderaadt if (pfound != NULL) 531*1e72d8d2Sderaadt { 532*1e72d8d2Sderaadt option_index = indfound; 533*1e72d8d2Sderaadt optind++; 534*1e72d8d2Sderaadt if (*nameend) 535*1e72d8d2Sderaadt { 536*1e72d8d2Sderaadt /* Don't test has_arg with >, because some C compilers don't 537*1e72d8d2Sderaadt allow it to be used on enums. */ 538*1e72d8d2Sderaadt if (pfound->has_arg) 539*1e72d8d2Sderaadt optarg = nameend + 1; 540*1e72d8d2Sderaadt else 541*1e72d8d2Sderaadt { 542*1e72d8d2Sderaadt if (opterr) 543*1e72d8d2Sderaadt { 544*1e72d8d2Sderaadt if (argv[optind - 1][1] == '-') 545*1e72d8d2Sderaadt /* --option */ 546*1e72d8d2Sderaadt fprintf (stderr, 547*1e72d8d2Sderaadt "%s: option `--%s' doesn't allow an argument\n", 548*1e72d8d2Sderaadt argv[0], pfound->name); 549*1e72d8d2Sderaadt else 550*1e72d8d2Sderaadt /* +option or -option */ 551*1e72d8d2Sderaadt fprintf (stderr, 552*1e72d8d2Sderaadt "%s: option `%c%s' doesn't allow an argument\n", 553*1e72d8d2Sderaadt argv[0], argv[optind - 1][0], pfound->name); 554*1e72d8d2Sderaadt } 555*1e72d8d2Sderaadt nextchar += strlen (nextchar); 556*1e72d8d2Sderaadt return '?'; 557*1e72d8d2Sderaadt } 558*1e72d8d2Sderaadt } 559*1e72d8d2Sderaadt else if (pfound->has_arg == 1) 560*1e72d8d2Sderaadt { 561*1e72d8d2Sderaadt if (optind < argc) 562*1e72d8d2Sderaadt optarg = argv[optind++]; 563*1e72d8d2Sderaadt else 564*1e72d8d2Sderaadt { 565*1e72d8d2Sderaadt if (opterr) 566*1e72d8d2Sderaadt fprintf (stderr, "%s: option `%s' requires an argument\n", 567*1e72d8d2Sderaadt argv[0], argv[optind - 1]); 568*1e72d8d2Sderaadt nextchar += strlen (nextchar); 569*1e72d8d2Sderaadt return optstring[0] == ':' ? ':' : '?'; 570*1e72d8d2Sderaadt } 571*1e72d8d2Sderaadt } 572*1e72d8d2Sderaadt nextchar += strlen (nextchar); 573*1e72d8d2Sderaadt if (longind != NULL) 574*1e72d8d2Sderaadt *longind = option_index; 575*1e72d8d2Sderaadt if (pfound->flag) 576*1e72d8d2Sderaadt { 577*1e72d8d2Sderaadt *(pfound->flag) = pfound->val; 578*1e72d8d2Sderaadt return 0; 579*1e72d8d2Sderaadt } 580*1e72d8d2Sderaadt return pfound->val; 581*1e72d8d2Sderaadt } 582*1e72d8d2Sderaadt 583*1e72d8d2Sderaadt /* Can't find it as a long option. If this is not getopt_long_only, 584*1e72d8d2Sderaadt or the option starts with '--' or is not a valid short 585*1e72d8d2Sderaadt option, then it's an error. 586*1e72d8d2Sderaadt Otherwise interpret it as a short option. */ 587*1e72d8d2Sderaadt if (!long_only || argv[optind][1] == '-' 588*1e72d8d2Sderaadt || my_index (optstring, *nextchar) == NULL) 589*1e72d8d2Sderaadt { 590*1e72d8d2Sderaadt if (opterr) 591*1e72d8d2Sderaadt { 592*1e72d8d2Sderaadt if (argv[optind][1] == '-') 593*1e72d8d2Sderaadt /* --option */ 594*1e72d8d2Sderaadt fprintf (stderr, "%s: unrecognized option `--%s'\n", 595*1e72d8d2Sderaadt argv[0], nextchar); 596*1e72d8d2Sderaadt else 597*1e72d8d2Sderaadt /* +option or -option */ 598*1e72d8d2Sderaadt fprintf (stderr, "%s: unrecognized option `%c%s'\n", 599*1e72d8d2Sderaadt argv[0], argv[optind][0], nextchar); 600*1e72d8d2Sderaadt } 601*1e72d8d2Sderaadt nextchar = (char *) ""; 602*1e72d8d2Sderaadt optind++; 603*1e72d8d2Sderaadt return '?'; 604*1e72d8d2Sderaadt } 605*1e72d8d2Sderaadt } 606*1e72d8d2Sderaadt 607*1e72d8d2Sderaadt /* Look at and handle the next short option-character. */ 608*1e72d8d2Sderaadt 609*1e72d8d2Sderaadt { 610*1e72d8d2Sderaadt char c = *nextchar++; 611*1e72d8d2Sderaadt char *temp = my_index (optstring, c); 612*1e72d8d2Sderaadt 613*1e72d8d2Sderaadt /* Increment `optind' when we start to process its last character. */ 614*1e72d8d2Sderaadt if (*nextchar == '\0') 615*1e72d8d2Sderaadt ++optind; 616*1e72d8d2Sderaadt 617*1e72d8d2Sderaadt if (temp == NULL || c == ':') 618*1e72d8d2Sderaadt { 619*1e72d8d2Sderaadt if (opterr) 620*1e72d8d2Sderaadt { 621*1e72d8d2Sderaadt if (posixly_correct) 622*1e72d8d2Sderaadt /* 1003.2 specifies the format of this message. */ 623*1e72d8d2Sderaadt fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); 624*1e72d8d2Sderaadt else 625*1e72d8d2Sderaadt fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); 626*1e72d8d2Sderaadt } 627*1e72d8d2Sderaadt optopt = c; 628*1e72d8d2Sderaadt return '?'; 629*1e72d8d2Sderaadt } 630*1e72d8d2Sderaadt if (temp[1] == ':') 631*1e72d8d2Sderaadt { 632*1e72d8d2Sderaadt if (temp[2] == ':') 633*1e72d8d2Sderaadt { 634*1e72d8d2Sderaadt /* This is an option that accepts an argument optionally. */ 635*1e72d8d2Sderaadt if (*nextchar != '\0') 636*1e72d8d2Sderaadt { 637*1e72d8d2Sderaadt optarg = nextchar; 638*1e72d8d2Sderaadt optind++; 639*1e72d8d2Sderaadt } 640*1e72d8d2Sderaadt else 641*1e72d8d2Sderaadt optarg = NULL; 642*1e72d8d2Sderaadt nextchar = NULL; 643*1e72d8d2Sderaadt } 644*1e72d8d2Sderaadt else 645*1e72d8d2Sderaadt { 646*1e72d8d2Sderaadt /* This is an option that requires an argument. */ 647*1e72d8d2Sderaadt if (*nextchar != '\0') 648*1e72d8d2Sderaadt { 649*1e72d8d2Sderaadt optarg = nextchar; 650*1e72d8d2Sderaadt /* If we end this ARGV-element by taking the rest as an arg, 651*1e72d8d2Sderaadt we must advance to the next element now. */ 652*1e72d8d2Sderaadt optind++; 653*1e72d8d2Sderaadt } 654*1e72d8d2Sderaadt else if (optind == argc) 655*1e72d8d2Sderaadt { 656*1e72d8d2Sderaadt if (opterr) 657*1e72d8d2Sderaadt { 658*1e72d8d2Sderaadt /* 1003.2 specifies the format of this message. */ 659*1e72d8d2Sderaadt fprintf (stderr, "%s: option requires an argument -- %c\n", 660*1e72d8d2Sderaadt argv[0], c); 661*1e72d8d2Sderaadt } 662*1e72d8d2Sderaadt optopt = c; 663*1e72d8d2Sderaadt if (optstring[0] == ':') 664*1e72d8d2Sderaadt c = ':'; 665*1e72d8d2Sderaadt else 666*1e72d8d2Sderaadt c = '?'; 667*1e72d8d2Sderaadt } 668*1e72d8d2Sderaadt else 669*1e72d8d2Sderaadt /* We already incremented `optind' once; 670*1e72d8d2Sderaadt increment it again when taking next ARGV-elt as argument. */ 671*1e72d8d2Sderaadt optarg = argv[optind++]; 672*1e72d8d2Sderaadt nextchar = NULL; 673*1e72d8d2Sderaadt } 674*1e72d8d2Sderaadt } 675*1e72d8d2Sderaadt return c; 676*1e72d8d2Sderaadt } 677*1e72d8d2Sderaadt } 678*1e72d8d2Sderaadt 679*1e72d8d2Sderaadt int 680*1e72d8d2Sderaadt getopt (argc, argv, optstring) 681*1e72d8d2Sderaadt int argc; 682*1e72d8d2Sderaadt char *const *argv; 683*1e72d8d2Sderaadt const char *optstring; 684*1e72d8d2Sderaadt { 685*1e72d8d2Sderaadt return _getopt_internal (argc, argv, optstring, 686*1e72d8d2Sderaadt (const struct option *) 0, 687*1e72d8d2Sderaadt (int *) 0, 688*1e72d8d2Sderaadt 0); 689*1e72d8d2Sderaadt } 690*1e72d8d2Sderaadt 691*1e72d8d2Sderaadt #endif /* _LIBC or not __GNU_LIBRARY__. */ 692*1e72d8d2Sderaadt 693*1e72d8d2Sderaadt #ifdef TEST 694*1e72d8d2Sderaadt 695*1e72d8d2Sderaadt /* Compile with -DTEST to make an executable for use in testing 696*1e72d8d2Sderaadt the above definition of `getopt'. */ 697*1e72d8d2Sderaadt 698*1e72d8d2Sderaadt int 699*1e72d8d2Sderaadt main (argc, argv) 700*1e72d8d2Sderaadt int argc; 701*1e72d8d2Sderaadt char **argv; 702*1e72d8d2Sderaadt { 703*1e72d8d2Sderaadt int c; 704*1e72d8d2Sderaadt int digit_optind = 0; 705*1e72d8d2Sderaadt 706*1e72d8d2Sderaadt while (1) 707*1e72d8d2Sderaadt { 708*1e72d8d2Sderaadt int this_option_optind = optind ? optind : 1; 709*1e72d8d2Sderaadt 710*1e72d8d2Sderaadt c = getopt (argc, argv, "abc:d:0123456789"); 711*1e72d8d2Sderaadt if (c == EOF) 712*1e72d8d2Sderaadt break; 713*1e72d8d2Sderaadt 714*1e72d8d2Sderaadt switch (c) 715*1e72d8d2Sderaadt { 716*1e72d8d2Sderaadt case '0': 717*1e72d8d2Sderaadt case '1': 718*1e72d8d2Sderaadt case '2': 719*1e72d8d2Sderaadt case '3': 720*1e72d8d2Sderaadt case '4': 721*1e72d8d2Sderaadt case '5': 722*1e72d8d2Sderaadt case '6': 723*1e72d8d2Sderaadt case '7': 724*1e72d8d2Sderaadt case '8': 725*1e72d8d2Sderaadt case '9': 726*1e72d8d2Sderaadt if (digit_optind != 0 && digit_optind != this_option_optind) 727*1e72d8d2Sderaadt printf ("digits occur in two different argv-elements.\n"); 728*1e72d8d2Sderaadt digit_optind = this_option_optind; 729*1e72d8d2Sderaadt printf ("option %c\n", c); 730*1e72d8d2Sderaadt break; 731*1e72d8d2Sderaadt 732*1e72d8d2Sderaadt case 'a': 733*1e72d8d2Sderaadt printf ("option a\n"); 734*1e72d8d2Sderaadt break; 735*1e72d8d2Sderaadt 736*1e72d8d2Sderaadt case 'b': 737*1e72d8d2Sderaadt printf ("option b\n"); 738*1e72d8d2Sderaadt break; 739*1e72d8d2Sderaadt 740*1e72d8d2Sderaadt case 'c': 741*1e72d8d2Sderaadt printf ("option c with value `%s'\n", optarg); 742*1e72d8d2Sderaadt break; 743*1e72d8d2Sderaadt 744*1e72d8d2Sderaadt case '?': 745*1e72d8d2Sderaadt break; 746*1e72d8d2Sderaadt 747*1e72d8d2Sderaadt default: 748*1e72d8d2Sderaadt printf ("?? getopt returned character code 0%o ??\n", c); 749*1e72d8d2Sderaadt } 750*1e72d8d2Sderaadt } 751*1e72d8d2Sderaadt 752*1e72d8d2Sderaadt if (optind < argc) 753*1e72d8d2Sderaadt { 754*1e72d8d2Sderaadt printf ("non-option ARGV-elements: "); 755*1e72d8d2Sderaadt while (optind < argc) 756*1e72d8d2Sderaadt printf ("%s ", argv[optind++]); 757*1e72d8d2Sderaadt printf ("\n"); 758*1e72d8d2Sderaadt } 759*1e72d8d2Sderaadt 760*1e72d8d2Sderaadt exit (0); 761*1e72d8d2Sderaadt } 762*1e72d8d2Sderaadt 763*1e72d8d2Sderaadt #endif /* TEST */ 764