1 /*****************************************************************************
3 * MODULE NAME : GETOPT.C
6 * This module contains code made available by IBM
7 * Corporation on an AS IS basis. Any one receiving the
8 * module is considered to be licensed under IBM copyrights
9 * to use the IBM-provided source code in any way he or she
10 * deems fit, including copying it, compiling it, modifying
11 * it, and redistributing it, with or without
12 * modifications. No license under any IBM patents or
13 * patent applications is to be implied from this copyright
16 * A user of the module should understand that IBM cannot
17 * provide technical support for the module and will not be
18 * responsible for any consequences of use of the program.
20 * Any notices, including this one, are not to be removed
21 * from the module without the prior written consent of
24 * AUTHOR: Original author:
25 * G. R. Blair (BOBBLAIR at AUSVM1)
26 * Internet: bobblair@bobblair.austin.ibm.com
28 * Extensively revised by:
29 * John Q. Walker II, Ph.D. (JOHHQ at RALVM6)
30 * Internet: johnq@ralvm6.vnet.ibm.com
33 /******************************************************************************
36 * The getopt() function is a command line parser. It returns the next
37 * option character in argv that matches an option character in opstring.
39 * The argv argument points to an array of argc+1 elements containing argc
40 * pointers to character strings followed by a null pointer.
42 * The opstring argument points to a string of option characters; if an
43 * option character is followed by a colon, the option is expected to have
44 * an argument that may or may not be separated from it by white space.
45 * The external variable optarg is set to point to the start of the option
46 * argument on return from getopt().
48 * The getopt() function places in optind the argv index of the next argument
49 * to be processed. The system initializes the external variable optind to
50 * 1 before the first call to getopt().
52 * When all options have been processed (that is, up to the first nonoption
53 * argument), getopt() returns EOF. The special option "--" may be used to
54 * delimit the end of the options; EOF will be returned, and "--" will be
57 * The getopt() function returns a question mark (?) when it encounters an
58 * option character not included in opstring. This error message can be
59 * disabled by setting opterr to zero. Otherwise, it returns the option
60 * character that was detected.
62 * If the special option "--" is detected, or all options have been
63 * processed, EOF is returned.
65 * Options are marked by either a minus sign (-) or a slash (/).
67 * No errors are defined.
69 #include <stdio.h> /* for EOF */
70 #include <string.h> /* for strchr() */
74 /* static (global) variables that are specified as exported by getopt() */
75 char *optarg
= NULL
; /* pointer to the start of the option argument */
76 int optind
= 1; /* number of the next argv[] to be evaluated */
77 int opterr
= 1; // non-zero if a question mark should be returned
78 // when a non-valid option character is detected
80 /* handle possible future character set concerns by putting this in a macro */
81 #define _next_char(string) (char)(*(string+1))
83 int getopt(int argc
, char *argv
[], char *opstring
)
85 static char *pIndexPosition
= NULL
; /* place inside current argv string */
86 char *pArgString
= NULL
; /* where to start from next */
87 char *pOptString
; // the string in our program
89 if (pIndexPosition
!= NULL
) {
90 // we last left off inside an argv string
91 if (*(++pIndexPosition
)) {
92 // there is more to come in the most recent argv
93 pArgString
= pIndexPosition
;
97 if (pArgString
== NULL
) {
98 // we didn't leave off in the middle of an argv string
100 // more command-line arguments than the argument count
101 pIndexPosition
= NULL
; /* not in the middle of anything */
102 return EOF
; /* used up all command-line arguments */
104 /*---------------------------------------------------------------------
105 * If the next argv[] is not an option, there can be no more options.
106 *-------------------------------------------------------------------*/
107 pArgString
= argv
[optind
++]; // set this to the next argument ptr
109 if (('/' != *pArgString
) && /* doesn't start with a slash or a dash? */
110 ('-' != *pArgString
)) {
111 --optind
; /* point to current arg once we're done */
112 optarg
= NULL
; /* no argument follows the option */
113 pIndexPosition
= NULL
; /* not in the middle of anything */
114 return EOF
; /* used up all the command-line flags */
117 // check for special end-of-flags markers
118 if ((strcmp(pArgString
, "-") == 0) ||
119 (strcmp(pArgString
, "--") == 0)) {
120 optarg
= NULL
; /* no argument follows the option */
121 pIndexPosition
= NULL
; /* not in the middle of anything */
122 return EOF
; /* encountered the special flag */
124 pArgString
++; /* look past the / or - */
127 if (':' == *pArgString
) { /* is it a colon? */
128 /*---------------------------------------------------------------------
129 * Rare case: if opterr is non-zero, return a question mark;
130 * otherwise, just return the colon we're on.
131 *-------------------------------------------------------------------*/
132 return (opterr
? (int)'?' : (int)':');
134 else if ((pOptString
= strchr(opstring
, *pArgString
)) == 0) {
135 /*---------------------------------------------------------------------
136 * The letter on the command-line wasn't any good.
137 *-------------------------------------------------------------------*/
138 optarg
= NULL
; /* no argument follows the option */
139 pIndexPosition
= NULL
; /* not in the middle of anything */
140 return (opterr
? (int)'?' : (int)*pArgString
);
142 /*---------------------------------------------------------------------
143 * The letter on the command-line matches one we expect to see
144 *-------------------------------------------------------------------*/
145 if (':' == _next_char(pOptString
)) { /* is the next letter a colon? */
146 /* It is a colon. Look for an argument string. */
147 if ('\0' != _next_char(pArgString
)) { /* argument in this argv? */
148 optarg
= &pArgString
[1]; /* Yes, it is */
150 /*-------------------------------------------------------------
151 * The argument string must be in the next argv.
152 * But, what if there is none (bad input from the user)?
153 * In that case, return the letter, and optarg as NULL.
154 *-----------------------------------------------------------*/
156 optarg
= argv
[optind
++];
159 return (opterr
? (int)'?' : (int)*pArgString
);
162 pIndexPosition
= NULL
; /* not in the middle of anything */
164 /* it's not a colon, so just return the letter */
165 optarg
= NULL
; /* no argument follows the option */
166 pIndexPosition
= pArgString
; /* point to the letter we're on */
168 return (int)*pArgString
; /* return the letter that matched */