% % This file was automatically produced at Sep 2 1995, 14:00:28 by % c++2latex -c getopt.c % \documentstyle[11pt]{article} \setlength{\textwidth}{15cm} \setlength{\textheight}{22.5cm} \setlength{\hoffset}{-2cm} \setlength{\voffset}{-2cm} \begin{document} \expandafter\ifx\csname indentation\endcsname\relax \newlength{\indentation}\fi \setlength{\indentation}{0.5em} \begin{flushleft} {$/\ast$\it{} Getopt for GNU.\mbox{}\\ \hspace*{3\indentation}Copyright (C) 1987, 1989 Free Software Foundation, Inc.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}This program is free software; you can redistribute it and/or modify\mbox{}\\ \hspace*{3\indentation}it under the terms of the GNU General Public License as published by\mbox{}\\ \hspace*{3\indentation}the Free Software Foundation; either version 1, or (at your option)\mbox{}\\ \hspace*{3\indentation}any later version.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}This program is distributed in the hope that it will be useful,\mbox{}\\ \hspace*{3\indentation}but WITHOUT ANY WARRANTY; without even the implied warranty of\mbox{}\\ \hspace*{3\indentation}MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\mbox{}\\ \hspace*{3\indentation}GNU General Public License for more details.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}You should have received a copy of the GNU General Public License\mbox{}\\ \hspace*{3\indentation}along with this program; if not, write to the Free Software\mbox{}\\ \hspace*{3\indentation}Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $\ast/$}\mbox{}\\ \newpage {$/\ast$\it{} This version of `getopt' appears to the caller like standard Unix `getopt'\mbox{}\\ \hspace*{3\indentation}but it behaves differently for the user, since it allows the user\mbox{}\\ \hspace*{3\indentation}to intersperse the options with the other arguments.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}As `getopt' works, it permutes the elements of `argv' so that,\mbox{}\\ \hspace*{3\indentation}when it is done, all the options precede everything else. Thus\mbox{}\\ \hspace*{3\indentation}all application programs are extended to handle flexible argument order.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}Setting the environment variable \_POSIX\_OPTION\_ORDER disables permutation.\mbox{}\\ \hspace*{3\indentation}Then the behavior is completely standard.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}GNU application programs can use a third alternative mode in which\mbox{}\\ \hspace*{3\indentation}they can distinguish the relative order of options and other arguments. $\ast/$}\mbox{}\\ \mbox{}\\ {\tt \#include} $<${\tt{}stdio.h}$>$\mbox{}\\ \mbox{}\\ {$/\ast$\it{} If compiled with GNU C, use the built-in alloca $\ast/$}\mbox{}\\ {\tt \#ifdef} \_\_GNUC\_\_\mbox{}\\ {\tt \#define} alloca \_\_builtin\_alloca\mbox{}\\ {\tt \#else} \hfill{$/\ast$\it{} not \_\_GNUC\_\_ $\ast/$}\mbox{}\\ {\tt \#ifdef} sparc\mbox{}\\ {\tt \#include} $<${\tt{}alloca.h}$>$\mbox{}\\ {\tt \#else}\mbox{}\\ {\bf char} $\ast$alloca ();\mbox{}\\ {\tt \#endif}\mbox{}\\ {\tt \#endif} \hfill{$/\ast$\it{} not \_\_GNUC\_\_ $\ast/$}\mbox{}\\ \mbox{}\\ {\tt \#ifdef} USG\mbox{}\\ {\tt \#define} bcopy(s, d, l) memcpy((d), (s), (l))\mbox{}\\ {\tt \#define} index strchr\mbox{}\\ {\tt \#endif}\mbox{}\\ \mbox{}\\ {\bf char} $\ast$getenv ();\mbox{}\\ {\bf char} $\ast$index ();\mbox{}\\ {\bf char} $\ast$malloc ();\mbox{}\\ \mbox{}\\ {$/\ast$\it{} For communication from `getopt' to the caller.\mbox{}\\ \hspace*{3\indentation}When `getopt' finds an option that takes an argument,\mbox{}\\ \hspace*{3\indentation}the argument value is returned here.\mbox{}\\ \hspace*{3\indentation}Also, when `ordering' is RETURN\_IN\_ORDER,\mbox{}\\ \hspace*{3\indentation}each non-option ARGV-element is returned here. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf char} $\ast$optarg = 0;\mbox{}\\ \mbox{}\\ {$/\ast$\it{} Index in ARGV of the next element to be scanned.\mbox{}\\ \hspace*{3\indentation}This is used for communication to and from the caller\mbox{}\\ \hspace*{3\indentation}and for communication between successive calls to `getopt'.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}On entry to `getopt', zero means this is the first call; initialize.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}When `getopt' returns EOF, this is the index of the first of the\mbox{}\\ \hspace*{3\indentation}non-option elements that the caller should itself scan.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}Otherwise, `optind' communicates from one call to the next\mbox{}\\ \hspace*{3\indentation}how much of ARGV has been scanned so far. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf int} optind = 0;\mbox{}\\ \mbox{}\\ {$/\ast$\it{} The next char to be scanned in the option-element\mbox{}\\ \hspace*{3\indentation}in which the last option character we returned was found.\mbox{}\\ \hspace*{3\indentation}This allows us to pick up the scan where we left off.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}If this is zero, or a null string, it means resume the scan\mbox{}\\ \hspace*{3\indentation}by advancing to the next ARGV-element. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf static} {\bf char} $\ast$nextchar;\mbox{}\\ \mbox{}\\ {$/\ast$\it{} Callers store zero here to inhibit the error message\mbox{}\\ \hspace*{3\indentation}for unrecognized options. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf int} opterr = 1;\mbox{}\\ \mbox{}\\ {$/\ast$\it{} Describe how to deal with options that follow non-option ARGV-elements.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}If the caller did not specify anything,\mbox{}\\ \hspace*{3\indentation}the default is REQUIRE\_ORDER if the environment variable\mbox{}\\ \hspace*{3\indentation}\_POSIX\_OPTION\_ORDER is defined, PERMUTE otherwise.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}REQUIRE\_ORDER means don't recognize them as options.\mbox{}\\ \hspace*{3\indentation}Stop option processing when the first non-option is seen.\mbox{}\\ \hspace*{3\indentation}This is what Unix does.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}PERMUTE is the default. We permute the contents of ARGV as we scan,\mbox{}\\ \hspace*{3\indentation}so that eventually all the options are at the end. This allows options\mbox{}\\ \hspace*{3\indentation}to be given in any order, even with programs that were not written to\mbox{}\\ \hspace*{3\indentation}expect this.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}RETURN\_IN\_ORDER is an option available to programs that were written\mbox{}\\ \hspace*{3\indentation}to expect options and other ARGV-elements in any order and that care about\mbox{}\\ \hspace*{3\indentation}the ordering of the two. We describe each non-option ARGV-element\mbox{}\\ \hspace*{3\indentation}as if it were the argument of an option with character code one.\mbox{}\\ \hspace*{3\indentation}Using `-' as the first character of the list of option characters\mbox{}\\ \hspace*{3\indentation}requests this mode of operation.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}The special argument `--' forces an end of option-scanning regardless\mbox{}\\ \hspace*{3\indentation}of the value of `ordering'. In the case of RETURN\_IN\_ORDER, only\mbox{}\\ \hspace*{3\indentation}`--' can cause `getopt' to return EOF with `optind' !$=$ ARGC. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf static} {\bf enum} \{ REQUIRE\_ORDER, PERMUTE, RETURN\_IN\_ORDER \} ordering;\mbox{}\\ \mbox{}\\ {$/\ast$\it{} Describe the long-named options requested by the application.\mbox{}\\ \hspace*{3\indentation}\_GETOPT\_LONG\_OPTIONS is a vector of `struct option' terminated by an\mbox{}\\ \hspace*{3\indentation}element containing a name which is zero.\mbox{}\\ \hspace*{3\indentation}The field `has\_arg' is 1 if the option takes an argument, \mbox{}\\ \hspace*{3\indentation}2 if it takes an optional argument. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf struct} option\mbox{}\\ \{\mbox{}\\ \hspace*{2\indentation}{\bf char} $\ast$name;\mbox{}\\ \hspace*{2\indentation}{\bf int} has\_arg;\mbox{}\\ \hspace*{2\indentation}{\bf int} $\ast$flag;\mbox{}\\ \hspace*{2\indentation}{\bf int} val;\mbox{}\\ \};\mbox{}\\ \mbox{}\\ {\bf struct} option $\ast$\_getopt\_long\_options;\mbox{}\\ \mbox{}\\ {\bf int} \_getopt\_long\_only = 0;\mbox{}\\ \mbox{}\\ {\tt \#if} 0\mbox{}\\ {$/\ast$\it{} This is an ugly kludge. Programs should use the opt\_index argument\mbox{}\\ \hspace*{3\indentation}to getopt\_long instead. $\ast/$}\mbox{}\\ {$/\ast$\it{} Name of long-named option actually found. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf char} $\ast$\_getopt\_option\_name;\mbox{}\\ {\tt \#endif}\mbox{}\\ \mbox{}\\ {$/\ast$\it{} Index in \_GETOPT\_LONG\_OPTIONS of the long-named option actually found.\mbox{}\\ \hspace*{3\indentation}Only valid when a long-named option was found. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf int} option\_index;\mbox{}\\ \newpage {$/\ast$\it{} Handle permutation of arguments. $\ast/$}\mbox{}\\ \mbox{}\\ {$/\ast$\it{} Describe the part of ARGV that contains non-options that have\mbox{}\\ \hspace*{3\indentation}been skipped. `first\_nonopt' is the index in ARGV of the first of them;\mbox{}\\ \hspace*{3\indentation}`last\_nonopt' is the index after the last of them. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf static} {\bf int} first\_nonopt;\mbox{}\\ {\bf static} {\bf int} last\_nonopt;\mbox{}\\ \mbox{}\\ {$/\ast$\it{} Exchange two adjacent subsequences of ARGV.\mbox{}\\ \hspace*{3\indentation}One subsequence is elements [first\_nonopt,last\_nonopt)\mbox{}\\ \hspace*{4\indentation}which contains all the non-options that have been skipped so far.\mbox{}\\ \hspace*{3\indentation}The other is elements [last\_nonopt,optind), which contains all\mbox{}\\ \hspace*{4\indentation}the options processed since those non-options were skipped.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}`first\_nonopt' and `last\_nonopt' are relocated so that they describe\mbox{}\\ \hspace*{4\indentation}the new indices of the non-options in ARGV after they are moved. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf static} {\bf void}\mbox{}\\ exchange (argv)\mbox{}\\ \hspace*{5\indentation}{\bf char} $\ast$$\ast$argv;\mbox{}\\ \{\mbox{}\\ \hspace*{2\indentation}{\bf int} nonopts\_size\mbox{}\\ \hspace*{4\indentation}= (last\_nonopt - first\_nonopt) $\ast$ {\bf sizeof} ({\bf char} $\ast$);\mbox{}\\ \hspace*{2\indentation}{\bf char} $\ast$$\ast$temp = ({\bf char} $\ast$$\ast$) alloca (nonopts\_size);\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}{$/\ast$\it{} Interchange the two blocks of data in argv. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}bcopy (\&argv[first\_nonopt], temp, nonopts\_size);\mbox{}\\ \hspace*{2\indentation}bcopy (\&argv[last\_nonopt], \&argv[first\_nonopt],\mbox{}\\ \hspace*{9\indentation}(optind - last\_nonopt) $\ast$ {\bf sizeof} ({\bf char} $\ast$));\mbox{}\\ \hspace*{2\indentation}bcopy (temp, \&argv[first\_nonopt + optind - last\_nonopt],\mbox{}\\ \hspace*{9\indentation}nonopts\_size);\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}{$/\ast$\it{} Update records for the slots the non-options now occupy. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}first\_nonopt += (optind - last\_nonopt);\mbox{}\\ \hspace*{2\indentation}last\_nonopt = optind;\mbox{}\\ \}\mbox{}\\ \newpage {$/\ast$\it{} Scan elements of ARGV (whose length is ARGC) for option characters\mbox{}\\ \hspace*{3\indentation}given in OPTSTRING.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}If an element of ARGV starts with '-', and is not exactly "-" or "--",\mbox{}\\ \hspace*{3\indentation}then it is an option element. The characters of this element\mbox{}\\ \hspace*{3\indentation}(aside from the initial '-') are option characters. If `getopt'\mbox{}\\ \hspace*{3\indentation}is called repeatedly, it returns successively each of the option characters\mbox{}\\ \hspace*{3\indentation}from each of the option elements.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}If `getopt' finds another option character, it returns that character,\mbox{}\\ \hspace*{3\indentation}updating `optind' and `nextchar' so that the next call to `getopt' can\mbox{}\\ \hspace*{3\indentation}resume the scan with the following option character or ARGV-element.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}If there are no more option characters, `getopt' returns `EOF'.\mbox{}\\ \hspace*{3\indentation}Then `optind' is the index in ARGV of the first ARGV-element\mbox{}\\ \hspace*{3\indentation}that is not an option. (The ARGV-elements have been permuted\mbox{}\\ \hspace*{3\indentation}so that those that are not options now come last.)\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}OPTSTRING is a string containing the legitimate option characters.\mbox{}\\ \hspace*{3\indentation}If an option character is seen that is not listed in OPTSTRING,\mbox{}\\ \hspace*{3\indentation}return '?' after printing an error message. If you set `opterr' to\mbox{}\\ \hspace*{3\indentation}zero, the error message is suppressed but we still return '?'.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}If a char in OPTSTRING is followed by a colon, that means it wants an arg,\mbox{}\\ \hspace*{3\indentation}so the following text in the same ARGV-element, or the text of the following\mbox{}\\ \hspace*{3\indentation}ARGV-element, is returned in `optarg'. Two colons mean an option that\mbox{}\\ \hspace*{3\indentation}wants an optional arg; if there is text in the current ARGV-element,\mbox{}\\ \hspace*{3\indentation}it is returned in `optarg', otherwise `optarg' is set to zero.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}If OPTSTRING starts with `-', it requests a different method of handling the\mbox{}\\ \hspace*{3\indentation}non-option ARGV-elements. See the comments about RETURN\_IN\_ORDER, above.\mbox{}\\ \mbox{}\\ \hspace*{3\indentation}Long-named options begin with `$+$' instead of `-'.\mbox{}\\ \hspace*{3\indentation}Their names may be abbreviated as long as the abbreviation is unique\mbox{}\\ \hspace*{3\indentation}or is an exact match for some defined option. If they have an\mbox{}\\ \hspace*{3\indentation}argument, it follows the option name in the same ARGV-element, separated\mbox{}\\ \hspace*{3\indentation}from the option name by a `$=$', or else the in next ARGV-element.\mbox{}\\ \hspace*{3\indentation}`getopt' returns 0 when it finds a long-named option. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf int}\mbox{}\\ getopt (argc, argv, optstring)\mbox{}\\ \hspace*{5\indentation}{\bf int} argc;\mbox{}\\ \hspace*{5\indentation}{\bf char} $\ast$$\ast$argv;\mbox{}\\ \hspace*{5\indentation}{\bf char} $\ast$optstring;\mbox{}\\ \{\mbox{}\\ \hspace*{2\indentation}optarg = 0;\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}{$/\ast$\it{} Initialize the internal data when the first call is made.\mbox{}\\ \hspace*{5\indentation}Start processing options with ARGV-element 1 (since ARGV-element 0\mbox{}\\ \hspace*{5\indentation}is the program name); the sequence of previously skipped\mbox{}\\ \hspace*{5\indentation}non-option ARGV-elements is empty. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}{\bf if} (optind == 0)\mbox{}\\ \hspace*{4\indentation}\{\mbox{}\\ \hspace*{6\indentation}first\_nonopt = last\_nonopt = optind = 1;\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}nextchar = 0;\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{$/\ast$\it{} Determine how to handle the ordering of options and nonoptions. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{\bf if} (optstring[0] == '-')\mbox{}\\ \hspace*{8\indentation}ordering = RETURN\_IN\_ORDER;\mbox{}\\ \hspace*{6\indentation}{\bf else} {\bf if} (getenv ({\tt"\_POSIX\_OPTION\_ORDER"}) $\neq$ 0)\mbox{}\\ \hspace*{8\indentation}ordering = REQUIRE\_ORDER;\mbox{}\\ \hspace*{6\indentation}{\bf else}\mbox{}\\ \hspace*{8\indentation}ordering = PERMUTE;\mbox{}\\ \hspace*{4\indentation}\}\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}{\bf if} (nextchar == 0 $\mid\mid$ $\ast$nextchar == 0)\mbox{}\\ \hspace*{4\indentation}\{\mbox{}\\ \hspace*{6\indentation}{\bf if} (ordering == PERMUTE)\mbox{}\\ \hspace*{8\indentation}\{\mbox{}\\ \hspace*{10\indentation}{$/\ast$\it{} If we have just processed some options following some non-options,\mbox{}\\ \hspace*{13\indentation}exchange them so that the options come first. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{10\indentation}{\bf if} (first\_nonopt $\neq$ last\_nonopt \&\& last\_nonopt $\neq$ optind)\mbox{}\\ \hspace*{12\indentation}exchange (argv);\mbox{}\\ \hspace*{10\indentation}{\bf else} {\bf if} (last\_nonopt $\neq$ optind)\mbox{}\\ \hspace*{12\indentation}first\_nonopt = optind;\mbox{}\\ \mbox{}\\ \hspace*{10\indentation}{$/\ast$\it{} Now skip any additional non-options\mbox{}\\ \hspace*{13\indentation}and extend the range of non-options previously skipped. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{10\indentation}{\bf while} (optind $<$ argc\mbox{}\\ \hspace*{17\indentation}\&\& (argv[optind][0] $\neq$ '-'\mbox{}\\ \hspace*{21\indentation}$\mid\mid$ argv[optind][1] == 0)\mbox{}\\ \hspace*{17\indentation}\&\& (\_getopt\_long\_options == 0\mbox{}\\ \hspace*{21\indentation}$\mid\mid$ argv[optind][0] $\neq$ '$+$'\mbox{}\\ \hspace*{21\indentation}$\mid\mid$ argv[optind][1] == 0))\mbox{}\\ \hspace*{12\indentation}optind++;\mbox{}\\ \hspace*{10\indentation}last\_nonopt = optind;\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{$/\ast$\it{} Special ARGV-element `--' means premature end of options.\mbox{}\\ \hspace*{9\indentation}Skip it like a null option,\mbox{}\\ \hspace*{9\indentation}then exchange with previous non-options as if it were an option,\mbox{}\\ \hspace*{9\indentation}then skip everything else like a non-option. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{\bf if} (optind $\neq$ argc \&\& !strcmp (argv[optind], {\tt"--"}))\mbox{}\\ \hspace*{8\indentation}\{\mbox{}\\ \hspace*{10\indentation}optind++;\mbox{}\\ \mbox{}\\ \hspace*{10\indentation}{\bf if} (first\_nonopt $\neq$ last\_nonopt \&\& last\_nonopt $\neq$ optind)\mbox{}\\ \hspace*{12\indentation}exchange (argv);\mbox{}\\ \hspace*{10\indentation}{\bf else} {\bf if} (first\_nonopt == last\_nonopt)\mbox{}\\ \hspace*{12\indentation}first\_nonopt = optind;\mbox{}\\ \hspace*{10\indentation}last\_nonopt = argc;\mbox{}\\ \mbox{}\\ \hspace*{10\indentation}optind = argc;\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{$/\ast$\it{} If we have done all the ARGV-elements, stop the scan\mbox{}\\ \hspace*{9\indentation}and back over any non-options that we skipped and permuted. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{\bf if} (optind == argc)\mbox{}\\ \hspace*{8\indentation}\{\mbox{}\\ \hspace*{10\indentation}{$/\ast$\it{} Set the next-arg-index to point at the non-options\mbox{}\\ \hspace*{13\indentation}that we previously skipped, so the caller will digest them. $\ast/$}\mbox{}\\ \hspace*{10\indentation}{\bf if} (first\_nonopt $\neq$ last\_nonopt)\mbox{}\\ \hspace*{12\indentation}optind = first\_nonopt;\mbox{}\\ \hspace*{10\indentation}{\bf return} EOF;\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \hspace*{9\indentation}\mbox{}\\ \hspace*{6\indentation}{$/\ast$\it{} If we have come to a non-option and did not permute it,\mbox{}\\ \hspace*{9\indentation}either stop the scan or describe it to the caller and pass it by. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{\bf if} ((argv[optind][0] $\neq$ '-' $\mid\mid$ argv[optind][1] == 0)\mbox{}\\ \hspace*{10\indentation}\&\& (\_getopt\_long\_options == 0\mbox{}\\ \hspace*{14\indentation}$\mid\mid$ argv[optind][0] $\neq$ '$+$' $\mid\mid$ argv[optind][1] == 0))\mbox{}\\ \hspace*{8\indentation}\{\mbox{}\\ \hspace*{10\indentation}{\bf if} (ordering == REQUIRE\_ORDER)\mbox{}\\ \hspace*{12\indentation}{\bf return} EOF;\mbox{}\\ \hspace*{10\indentation}optarg = argv[optind++];\mbox{}\\ {\tt \#if} 0\mbox{}\\ \hspace*{10\indentation}\_getopt\_option\_name = 0;\mbox{}\\ {\tt \#endif}\mbox{}\\ \hspace*{10\indentation}{\bf return} 1;\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{$/\ast$\it{} We have found another option-ARGV-element.\mbox{}\\ \hspace*{9\indentation}Start decoding its characters. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}nextchar = argv[optind] + 1;\mbox{}\\ \hspace*{4\indentation}\}\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}{\bf if} (\_getopt\_long\_options $\neq$ 0\mbox{}\\ \hspace*{6\indentation}\&\& (argv[optind][0] == '$+$'\mbox{}\\ \hspace*{10\indentation}$\mid\mid$ (\_getopt\_long\_only \&\& argv[optind][0] == '-'))\mbox{}\\ \hspace*{6\indentation})\mbox{}\\ \hspace*{4\indentation}\{\mbox{}\\ \hspace*{6\indentation}{\bf struct} option $\ast$p;\mbox{}\\ \hspace*{6\indentation}{\bf char} $\ast$s = nextchar;\mbox{}\\ \hspace*{6\indentation}{\bf int} exact = 0;\mbox{}\\ \hspace*{6\indentation}{\bf int} ambig = 0;\mbox{}\\ \hspace*{6\indentation}{\bf struct} option $\ast$pfound = 0;\mbox{}\\ \hspace*{6\indentation}{\bf int} indfound;\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{\bf while} ($\ast$s \&\& $\ast$s $\neq$ '$=$') s++;\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{$/\ast$\it{} Test all options for either exact match or abbreviated matches. $\ast/$}\mbox{}\\ \hspace*{6\indentation}{\bf for} (p = \_getopt\_long\_options, option\_index = 0; p$\rightarrow$name; \mbox{}\\ \hspace*{11\indentation}p++, option\_index++)\mbox{}\\ \hspace*{8\indentation}{\bf if} (!strncmp (p$\rightarrow$name, nextchar, s - nextchar))\mbox{}\\ \hspace*{10\indentation}\{\mbox{}\\ \hspace*{12\indentation}{\bf if} (s - nextchar == strlen (p$\rightarrow$name))\mbox{}\\ \hspace*{14\indentation}\{\mbox{}\\ \hspace*{16\indentation}{$/\ast$\it{} Exact match found. $\ast/$}\mbox{}\\ \hspace*{16\indentation}pfound = p;\mbox{}\\ \hspace*{16\indentation}indfound = option\_index;\mbox{}\\ \hspace*{16\indentation}exact = 1;\mbox{}\\ \hspace*{16\indentation}{\bf break};\mbox{}\\ \hspace*{14\indentation}\}\mbox{}\\ \hspace*{12\indentation}{\bf else} {\bf if} (pfound == 0)\mbox{}\\ \hspace*{14\indentation}\{\mbox{}\\ \hspace*{16\indentation}{$/\ast$\it{} First nonexact match found. $\ast/$}\mbox{}\\ \hspace*{16\indentation}pfound = p;\mbox{}\\ \hspace*{16\indentation}indfound = option\_index;\mbox{}\\ \hspace*{14\indentation}\}\mbox{}\\ \hspace*{12\indentation}{\bf else}\mbox{}\\ \hspace*{14\indentation}{$/\ast$\it{} Second nonexact match found. $\ast/$}\mbox{}\\ \hspace*{14\indentation}ambig = 1;\mbox{}\\ \hspace*{10\indentation}\}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{\bf if} (ambig \&\& !exact)\mbox{}\\ \hspace*{8\indentation}\{\mbox{}\\ \hspace*{10\indentation}fprintf (stderr, {\tt"\%s: option `\%s' is ambiguous$\backslash$n"},\mbox{}\\ \hspace*{19\indentation}argv[0], argv[optind]);\mbox{}\\ \hspace*{10\indentation}nextchar += strlen (nextchar); \mbox{}\\ \hspace*{10\indentation}{\bf return} '?';\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{\bf if} (pfound $\neq$ 0)\mbox{}\\ \hspace*{8\indentation}\{\mbox{}\\ \hspace*{10\indentation}option\_index = indfound;\mbox{}\\ \hspace*{10\indentation}optind++;\mbox{}\\ \hspace*{10\indentation}{\bf if} ($\ast$s)\mbox{}\\ \hspace*{12\indentation}\{\mbox{}\\ \hspace*{14\indentation}{\bf if} (pfound$\rightarrow$has\_arg $>$ 0)\mbox{}\\ \hspace*{16\indentation}optarg = s + 1;\mbox{}\\ \hspace*{14\indentation}{\bf else}\mbox{}\\ \hspace*{16\indentation}\{\mbox{}\\ \hspace*{18\indentation}fprintf (stderr,\mbox{}\\ \hspace*{27\indentation}{\tt"\%s: option `\%c\%s' doesn't allow an argument$\backslash$n"},\mbox{}\\ \hspace*{27\indentation}argv[0], argv[optind - 1][0], pfound$\rightarrow$name);\mbox{}\\ \hspace*{18\indentation}nextchar += strlen (nextchar); \mbox{}\\ \hspace*{18\indentation}{\bf return} '?';\mbox{}\\ \hspace*{16\indentation}\}\mbox{}\\ \hspace*{12\indentation}\}\mbox{}\\ \hspace*{10\indentation}{\bf else} {\bf if} (pfound$\rightarrow$has\_arg)\mbox{}\\ \hspace*{12\indentation}\{\mbox{}\\ \hspace*{14\indentation}{\bf if} (optind $<$ argc)\mbox{}\\ \hspace*{16\indentation}optarg = argv[optind++];\mbox{}\\ \hspace*{14\indentation}{\bf else} {\bf if} (pfound$\rightarrow$has\_arg $\neq$ 2)\mbox{}\\ \hspace*{16\indentation}\{\mbox{}\\ \hspace*{18\indentation}fprintf (stderr, {\tt"\%s: option `\%s' requires an argument$\backslash$n"},\mbox{}\\ \hspace*{27\indentation}argv[0], argv[optind - 1]);\mbox{}\\ \hspace*{18\indentation}nextchar += strlen (nextchar); \mbox{}\\ \hspace*{18\indentation}{\bf return} '?';\mbox{}\\ \hspace*{16\indentation}\}\mbox{}\\ \hspace*{12\indentation}\}\mbox{}\\ {\tt \#if} 0\mbox{}\\ \hspace*{10\indentation}\_getopt\_option\_name = pfound$\rightarrow$name;\mbox{}\\ {\tt \#endif}\mbox{}\\ \hspace*{10\indentation}nextchar += strlen (nextchar);\mbox{}\\ \hspace*{10\indentation}{\bf if} (pfound$\rightarrow$flag)\mbox{}\\ \hspace*{12\indentation}$\ast$(pfound$\rightarrow$flag) = pfound$\rightarrow$val;\mbox{}\\ \hspace*{10\indentation}{\bf return} 0;\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \hspace*{6\indentation}{$/\ast$\it{} Can't find it as a long option. If this is getopt\_long\_only,\mbox{}\\ \hspace*{9\indentation}and the option starts with '-' and is a valid short\mbox{}\\ \hspace*{9\indentation}option, then interpret it as a short option. Otherwise it's\mbox{}\\ \hspace*{9\indentation}an error. $\ast/$}\mbox{}\\ \hspace*{6\indentation}{\bf if} (\_getopt\_long\_only == 0 $\mid\mid$ argv[optind][0] == '$+$' $\mid\mid$\mbox{}\\ \hspace*{10\indentation}index (optstring, $\ast$nextchar) == 0)\mbox{}\\ \hspace*{8\indentation}\{\mbox{}\\ \hspace*{10\indentation}{\bf if} (opterr $\neq$ 0)\mbox{}\\ \hspace*{12\indentation}fprintf (stderr, {\tt"\%s: unrecognized option `\%c\%s'$\backslash$n"},\mbox{}\\ \hspace*{21\indentation}argv[0], argv[optind][0], nextchar);\mbox{}\\ \hspace*{10\indentation}nextchar += strlen (nextchar); \mbox{}\\ \hspace*{10\indentation}{\bf return} '?';\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \hspace*{4\indentation}\}\mbox{}\\ \hspace*{1\indentation}\mbox{}\\ \hspace*{2\indentation}{$/\ast$\it{} Look at and handle the next option-character. $\ast/$}\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}\{\mbox{}\\ \hspace*{4\indentation}{\bf char} c = $\ast$nextchar++;\mbox{}\\ \hspace*{4\indentation}{\bf char} $\ast$temp = index (optstring, c);\mbox{}\\ \mbox{}\\ \hspace*{4\indentation}{$/\ast$\it{} Increment `optind' when we start to process its last character. $\ast/$}\mbox{}\\ \hspace*{4\indentation}{\bf if} ($\ast$nextchar == 0)\mbox{}\\ \hspace*{6\indentation}optind++;\mbox{}\\ \mbox{}\\ \hspace*{4\indentation}{\bf if} (temp == 0 $\mid\mid$ c == ':')\mbox{}\\ \hspace*{6\indentation}\{\mbox{}\\ \hspace*{8\indentation}{\bf if} (opterr $\neq$ 0)\mbox{}\\ \hspace*{10\indentation}\{\mbox{}\\ \hspace*{12\indentation}{\bf if} (c $<$ 040 $\mid\mid$ c $\geq$ 0177)\mbox{}\\ \hspace*{14\indentation}fprintf (stderr, {\tt"\%s: unrecognized option, character code 0\%o$\backslash$n"},\mbox{}\\ \hspace*{23\indentation}argv[0], c);\mbox{}\\ \hspace*{12\indentation}{\bf else}\mbox{}\\ \hspace*{14\indentation}fprintf (stderr, {\tt"\%s: unrecognized option `-\%c'$\backslash$n"},\mbox{}\\ \hspace*{23\indentation}argv[0], c);\mbox{}\\ \hspace*{10\indentation}\}\mbox{}\\ \hspace*{8\indentation}{\bf return} '?';\mbox{}\\ \hspace*{6\indentation}\}\mbox{}\\ \hspace*{4\indentation}{\bf if} (temp[1] == ':')\mbox{}\\ \hspace*{6\indentation}\{\mbox{}\\ \hspace*{8\indentation}{\bf if} (temp[2] == ':')\mbox{}\\ \hspace*{10\indentation}\{\mbox{}\\ \hspace*{12\indentation}{$/\ast$\it{} This is an option that accepts an argument optionally. $\ast/$}\mbox{}\\ \hspace*{12\indentation}{\bf if} ($\ast$nextchar $\neq$ 0)\mbox{}\\ \hspace*{14\indentation}\{\mbox{}\\ \hspace*{16\indentation}optarg = nextchar;\mbox{}\\ \hspace*{16\indentation}optind++;\mbox{}\\ \hspace*{14\indentation}\}\mbox{}\\ \hspace*{12\indentation}{\bf else}\mbox{}\\ \hspace*{14\indentation}optarg = 0;\mbox{}\\ \hspace*{12\indentation}nextchar = 0;\mbox{}\\ \hspace*{10\indentation}\}\mbox{}\\ \hspace*{8\indentation}{\bf else}\mbox{}\\ \hspace*{10\indentation}\{\mbox{}\\ \hspace*{12\indentation}{$/\ast$\it{} This is an option that requires an argument. $\ast/$}\mbox{}\\ \hspace*{12\indentation}{\bf if} ($\ast$nextchar $\neq$ 0)\mbox{}\\ \hspace*{14\indentation}\{\mbox{}\\ \hspace*{16\indentation}optarg = nextchar;\mbox{}\\ \hspace*{16\indentation}{$/\ast$\it{} If we end this ARGV-element by taking the rest as an arg,\mbox{}\\ \hspace*{19\indentation}we must advance to the next element now. $\ast/$}\mbox{}\\ \hspace*{16\indentation}optind++;\mbox{}\\ \hspace*{14\indentation}\}\mbox{}\\ \hspace*{12\indentation}{\bf else} {\bf if} (optind == argc)\mbox{}\\ \hspace*{14\indentation}\{\mbox{}\\ \hspace*{16\indentation}{\bf if} (opterr $\neq$ 0)\mbox{}\\ \hspace*{18\indentation}fprintf (stderr, {\tt"\%s: option `-\%c' requires an argument$\backslash$n"},\mbox{}\\ \hspace*{27\indentation}argv[0], c);\mbox{}\\ \hspace*{16\indentation}c = '?';\mbox{}\\ \hspace*{14\indentation}\}\mbox{}\\ \hspace*{12\indentation}{\bf else}\mbox{}\\ \hspace*{14\indentation}{$/\ast$\it{} We already incremented `optind' once;\mbox{}\\ \hspace*{17\indentation}increment it again when taking next ARGV-elt as argument. $\ast/$}\mbox{}\\ \hspace*{14\indentation}optarg = argv[optind++];\mbox{}\\ \hspace*{12\indentation}nextchar = 0;\mbox{}\\ \hspace*{10\indentation}\}\mbox{}\\ \hspace*{6\indentation}\}\mbox{}\\ \hspace*{4\indentation}{\bf return} c;\mbox{}\\ \hspace*{2\indentation}\}\mbox{}\\ \}\mbox{}\\ \newpage {\tt \#ifdef} TEST\mbox{}\\ \mbox{}\\ {$/\ast$\it{} Compile with -DTEST to make an executable for use in testing\mbox{}\\ \hspace*{3\indentation}the above definition of `getopt'. $\ast/$}\mbox{}\\ \mbox{}\\ {\bf int}\mbox{}\\ main (argc, argv)\mbox{}\\ \hspace*{5\indentation}{\bf int} argc;\mbox{}\\ \hspace*{5\indentation}{\bf char} $\ast$$\ast$argv;\mbox{}\\ \{\mbox{}\\ \hspace*{2\indentation}{\bf char} c;\mbox{}\\ \hspace*{2\indentation}{\bf int} digit\_optind = 0;\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}{\bf while} (1)\mbox{}\\ \hspace*{4\indentation}\{\mbox{}\\ \hspace*{6\indentation}{\bf int} this\_option\_optind = optind;\mbox{}\\ \hspace*{6\indentation}{\bf if} ((c = getopt (argc, argv, {\tt"abc:d:0123456789"})) == EOF)\mbox{}\\ \hspace*{8\indentation}{\bf break};\mbox{}\\ \mbox{}\\ \hspace*{6\indentation}{\bf switch} (c)\mbox{}\\ \hspace*{8\indentation}\{\mbox{}\\ \hspace*{8\indentation}{\bf case} '0':\mbox{}\\ \hspace*{8\indentation}{\bf case} '1':\mbox{}\\ \hspace*{8\indentation}{\bf case} '2':\mbox{}\\ \hspace*{8\indentation}{\bf case} '3':\mbox{}\\ \hspace*{8\indentation}{\bf case} '4':\mbox{}\\ \hspace*{8\indentation}{\bf case} '5':\mbox{}\\ \hspace*{8\indentation}{\bf case} '6':\mbox{}\\ \hspace*{8\indentation}{\bf case} '7':\mbox{}\\ \hspace*{8\indentation}{\bf case} '8':\mbox{}\\ \hspace*{8\indentation}{\bf case} '9':\mbox{}\\ \hspace*{10\indentation}{\bf if} (digit\_optind $\neq$ 0 \&\& digit\_optind $\neq$ this\_option\_optind)\mbox{}\\ \hspace*{12\indentation}printf ({\tt"digits occur in two different argv-elements.$\backslash$n"});\mbox{}\\ \hspace*{10\indentation}digit\_optind = this\_option\_optind;\mbox{}\\ \hspace*{10\indentation}printf ({\tt"option \%c$\backslash$n"}, c);\mbox{}\\ \hspace*{10\indentation}{\bf break};\mbox{}\\ \mbox{}\\ \hspace*{8\indentation}{\bf case} 'a':\mbox{}\\ \hspace*{10\indentation}printf ({\tt"option a$\backslash$n"});\mbox{}\\ \hspace*{10\indentation}{\bf break};\mbox{}\\ \mbox{}\\ \hspace*{8\indentation}{\bf case} 'b':\mbox{}\\ \hspace*{10\indentation}printf ({\tt"option b$\backslash$n"});\mbox{}\\ \hspace*{10\indentation}{\bf break};\mbox{}\\ \mbox{}\\ \hspace*{8\indentation}{\bf case} 'c':\mbox{}\\ \hspace*{10\indentation}printf ({\tt"option c with value `\%s'$\backslash$n"}, optarg);\mbox{}\\ \hspace*{10\indentation}{\bf break};\mbox{}\\ \mbox{}\\ \hspace*{8\indentation}{\bf case} '?':\mbox{}\\ \hspace*{10\indentation}{\bf break};\mbox{}\\ \mbox{}\\ \hspace*{8\indentation}{\bf default}:\mbox{}\\ \hspace*{10\indentation}printf ({\tt"?? getopt returned character code 0\%o ??$\backslash$n"}, c);\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \hspace*{4\indentation}\}\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}{\bf if} (optind $<$ argc)\mbox{}\\ \hspace*{4\indentation}\{\mbox{}\\ \hspace*{6\indentation}printf ({\tt"non-option ARGV-elements: "});\mbox{}\\ \hspace*{6\indentation}{\bf while} (optind $<$ argc)\mbox{}\\ \hspace*{8\indentation}printf ({\tt"\%s "}, argv[optind++]);\mbox{}\\ \hspace*{6\indentation}printf ({\tt"$\backslash$n"});\mbox{}\\ \hspace*{4\indentation}\}\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}{\bf return} 0;\mbox{}\\ \}\mbox{}\\ \mbox{}\\ {\tt \#endif} \hfill{$/\ast$\it{} TEST $\ast/$}\mbox{}\\ \end{flushleft} \end{document}