16
|
1 // XGetopt.cpp Version 1.1
|
|
2 //
|
|
3 // Author: Hans Dietrich
|
|
4 // hdietrich2@hotmail.com
|
|
5 //
|
|
6 // Modified: David Smith
|
|
7 // dave.s@earthcorp.com
|
|
8 // Moved two char declarations from body of function so
|
|
9 // that it can compile as a C function.
|
|
10 // Thanks so much Hans
|
|
11 //
|
|
12 // This software is released into the public domain.
|
|
13 // You are free to use it in any way you like.
|
|
14 //
|
|
15 // This software is provided "as is" with no expressed
|
|
16 // or implied warranty. I accept no liability for any
|
|
17 // damage or loss of business that this software may cause.
|
|
18 //
|
|
19 ///////////////////////////////////////////////////////////////////////////////
|
|
20
|
|
21 #include <stdio.h>
|
|
22 #include <string.h>
|
|
23 #include "XGetopt.h"
|
|
24
|
|
25 ///////////////////////////////////////////////////////////////////////////////
|
|
26 //
|
|
27 // X G e t o p t . c p p
|
|
28 //
|
|
29 //
|
|
30 // NAME
|
|
31 // getopt -- parse command line options
|
|
32 //
|
|
33 // SYNOPSIS
|
|
34 // int getopt(int argc, char *argv[], char *optstring)
|
|
35 //
|
|
36 // extern char *optarg;
|
|
37 // extern int optind;
|
|
38 //
|
|
39 // DESCRIPTION
|
|
40 // The getopt() function parses the command line arguments. Its
|
|
41 // arguments argc and argv are the argument count and array as
|
|
42 // passed into the application on program invocation. In the case
|
|
43 // of Visual C++ programs, argc and argv are available via the
|
|
44 // variables __argc and __argv (double underscores), respectively.
|
|
45 // getopt returns the next option letter in argv that matches a
|
|
46 // letter in optstring.
|
|
47 //
|
|
48 // optstring is a string of recognized option letters; if a letter
|
|
49 // is followed by a colon, the option is expected to have an argument
|
|
50 // that may or may not be separated from it by white space. optarg
|
|
51 // is set to point to the start of the option argument on return from
|
|
52 // getopt.
|
|
53 //
|
|
54 // Option letters may be combined, e.g., "-ab" is equivalent to
|
|
55 // "-a -b". Option letters are case sensitive.
|
|
56 //
|
|
57 // getopt places in the external variable optind the argv index
|
|
58 // of the next argument to be processed. optind is initialized
|
|
59 // to 0 before the first call to getopt.
|
|
60 //
|
|
61 // When all options have been processed (i.e., up to the first
|
|
62 // non-option argument), getopt returns EOF, optarg will point
|
|
63 // to the argument, and optind will be set to the argv index of
|
|
64 // the argument. If there are no non-option arguments, optarg
|
|
65 // will be set to NULL.
|
|
66 //
|
|
67 // The special option "--" may be used to delimit the end of the
|
|
68 // options; EOF will be returned, and "--" (and everything after it)
|
|
69 // will be skipped.
|
|
70 //
|
|
71 // RETURN VALUE
|
|
72 // For option letters contained in the string optstring, getopt
|
|
73 // will return the option letter. getopt returns a question mark (?)
|
|
74 // when it encounters an option letter not included in optstring.
|
|
75 // EOF is returned when processing is finished.
|
|
76 //
|
|
77 // BUGS
|
|
78 // 1) Long options are not supported.
|
|
79 // 2) The GNU double-colon extension is not supported.
|
|
80 // 3) The environment variable POSIXLY_CORRECT is not supported.
|
|
81 // 4) The + syntax is not supported.
|
|
82 // 5) The automatic permutation of arguments is not supported.
|
|
83 // 6) This implementation of getopt() returns EOF if an error is
|
|
84 // encountered, instead of -1 as the latest standard requires.
|
|
85 //
|
|
86 // EXAMPLE
|
|
87 // BOOL CMyApp::ProcessCommandLine(int argc, char *argv[])
|
|
88 // {
|
|
89 // int c;
|
|
90 //
|
|
91 // while ((c = getopt(argc, argv, "aBn:")) != EOF)
|
|
92 // {
|
|
93 // switch (c)
|
|
94 // {
|
|
95 // case 'a':
|
|
96 // TRACE(_T("option a\n"));
|
|
97 // //
|
|
98 // // set some flag here
|
|
99 // //
|
|
100 // break;
|
|
101 //
|
|
102 // case 'B':
|
|
103 // TRACE( _T("option B\n"));
|
|
104 // //
|
|
105 // // set some other flag here
|
|
106 // //
|
|
107 // break;
|
|
108 //
|
|
109 // case 'n':
|
|
110 // TRACE(_T("option n: value=%d\n"), atoi(optarg));
|
|
111 // //
|
|
112 // // do something with value here
|
|
113 // //
|
|
114 // break;
|
|
115 //
|
|
116 // case '?':
|
|
117 // TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
|
|
118 // return FALSE;
|
|
119 // break;
|
|
120 //
|
|
121 // default:
|
|
122 // TRACE(_T("WARNING: no handler for option %c\n"), c);
|
|
123 // return FALSE;
|
|
124 // break;
|
|
125 // }
|
|
126 // }
|
|
127 // //
|
|
128 // // check for non-option args here
|
|
129 // //
|
|
130 // return TRUE;
|
|
131 // }
|
|
132 //
|
|
133 ///////////////////////////////////////////////////////////////////////////////
|
|
134
|
|
135 char *optarg; // global argument pointer
|
|
136 int optind = 0; // global argv index
|
|
137
|
|
138 int getopt(int argc, char *argv[], char *optstring)
|
|
139 {
|
|
140 static char *next = NULL;
|
|
141 char c, *cp;
|
|
142 if (optind == 0)
|
|
143 next = NULL;
|
|
144
|
|
145 optarg = NULL;
|
|
146
|
|
147 if (next == NULL || *next == '\0')
|
|
148 {
|
|
149 if (optind == 0)
|
|
150 optind++;
|
|
151
|
|
152 if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
|
|
153 {
|
|
154 optarg = NULL;
|
|
155 if (optind < argc)
|
|
156 optarg = argv[optind];
|
|
157 return EOF;
|
|
158 }
|
|
159
|
|
160 if (strcmp(argv[optind], "--") == 0)
|
|
161 {
|
|
162 optind++;
|
|
163 optarg = NULL;
|
|
164 if (optind < argc)
|
|
165 optarg = argv[optind];
|
|
166 return EOF;
|
|
167 }
|
|
168
|
|
169 next = argv[optind]+1;
|
|
170 optind++;
|
|
171 }
|
|
172
|
|
173 c = *next++;
|
|
174 cp = strchr(optstring, c);
|
|
175
|
|
176 if (cp == NULL || c == ':')
|
|
177 return '?';
|
|
178
|
|
179 cp++;
|
|
180 if (*cp == ':')
|
|
181 {
|
|
182 if (*next != '\0')
|
|
183 {
|
|
184 optarg = next;
|
|
185 next = NULL;
|
|
186 }
|
|
187 else if (optind < argc)
|
|
188 {
|
|
189 optarg = argv[optind];
|
|
190 optind++;
|
|
191 }
|
|
192 else
|
|
193 {
|
|
194 return '?';
|
|
195 }
|
|
196 }
|
|
197
|
|
198 return c;
|
|
199 }
|