Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: compat/win/getopt.c

Issue 1119783005: win: get tools/crashpad_database_util mostly working (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: missing header Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /****************************************************************************
2
3 getopt.c - Read command line options
4
5 AUTHOR: Gregory Pietsch
6 CREATED Fri Jan 10 21:13:05 1997
7
8 DESCRIPTION:
9
10 The getopt() function parses the command line arguments. Its arguments argc
11 and argv are the argument count and array as passed to the main() function
12 on program invocation. The argument optstring is a list of available option
13 characters. If such a character is followed by a colon (`:'), the option
14 takes an argument, which is placed in optarg. If such a character is
15 followed by two colons, the option takes an optional argument, which is
16 placed in optarg. If the option does not take an argument, optarg is NULL.
17
18 The external variable optind is the index of the next array element of argv
19 to be processed; it communicates from one call to the next which element to
20 process.
21
22 The getopt_long() function works like getopt() except that it also accepts
23 long options started by two dashes `--'. If these take values, it is either
24 in the form
25
26 --arg=value
27
28 or
29
30 --arg value
31
32 It takes the additional arguments longopts which is a pointer to the first
33 element of an array of type GETOPT_LONG_OPTION_T. The last element of the
34 array has to be filled with NULL for the name field.
35
36 The longind pointer points to the index of the current long option relative
37 to longopts if it is non-NULL.
38
39 The getopt() function returns the option character if the option was found
40 successfully, `:' if there was a missing parameter for one of the options,
41 `?' for an unknown option character, and EOF for the end of the option list.
42
43 The getopt_long() function's return value is described in the header file.
44
45 The function getopt_long_only() is identical to getopt_long(), except that a
46 plus sign `+' can introduce long options as well as `--'.
47
48 The following describes how to deal with options that follow non-option
49 argv-elements.
50
51 If the caller did not specify anything, the default is REQUIRE_ORDER if the
52 environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise.
53
54 REQUIRE_ORDER means don't recognize them as options; stop option processing
55 when the first non-option is seen. This is what Unix does. This mode of
56 operation is selected by either setting the environment variable
57 POSIXLY_CORRECT, or using `+' as the first character of the optstring
58 parameter.
59
60 PERMUTE is the default. We permute the contents of ARGV as we scan, so that
61 eventually all the non-options are at the end. This allows options to be
62 given in any order, even with programs that were not written to expect this.
63
64 RETURN_IN_ORDER is an option available to programs that were written to
65 expect options and other argv-elements in any order and that care about the
66 ordering of the two. We describe each non-option argv-element as if it were
67 the argument of an option with character code 1. Using `-' as the first
68 character of the optstring parameter selects this mode of operation.
69
70 The special argument `--' forces an end of option-scanning regardless of the
71 value of ordering. In the case of RETURN_IN_ORDER, only `--' can cause
72 getopt() and friends to return EOF with optind != argc.
73
74 COPYRIGHT NOTICE AND DISCLAIMER:
75
76 Copyright (C) 1997 Gregory Pietsch
77
78 This file and the accompanying getopt.h header file are hereby placed in the
79 public domain without restrictions. Just give the author credit, don't
80 claim you wrote it or prevent anyone else from using it.
81
82 Gregory Pietsch's current e-mail address:
83 gpietsch@comcast.net
84 ****************************************************************************/
85
86 /* include files */
87 #include <stdio.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #ifndef GETOPT_H
91 #include "getopt.h"
92 #endif
93
94 #ifdef _MSC_VER
95 #pragma warning(disable: 4267)
96 #endif
97
98 /* macros */
99
100 /* types */
101 typedef enum GETOPT_ORDERING_T
102 {
103 PERMUTE,
104 RETURN_IN_ORDER,
105 REQUIRE_ORDER
106 } GETOPT_ORDERING_T;
107
108 /* globally-defined variables */
109 char *optarg = NULL;
110 int optind = 0;
111 int opterr = 1;
112 int optopt = '?';
113
114 /* functions */
115
116 /* reverse_argv_elements: reverses num elements starting at argv */
117 static void
118 reverse_argv_elements (char **argv, int num)
119 {
120 int i;
121 char *tmp;
122
123 for (i = 0; i < (num >> 1); i++)
124 {
125 tmp = argv[i];
126 argv[i] = argv[num - i - 1];
127 argv[num - i - 1] = tmp;
128 }
129 }
130
131 /* permute: swap two blocks of argv-elements given their lengths */
132 static void
133 permute (char **argv, int len1, int len2)
134 {
135 reverse_argv_elements (argv, len1);
136 reverse_argv_elements (argv, len1 + len2);
137 reverse_argv_elements (argv, len2);
138 }
139
140 /* is_option: is this argv-element an option or the end of the option list? */
141 static int
142 is_option (char *argv_element, int only)
143 {
144 return ((argv_element == NULL)
145 || (argv_element[0] == '-') || (only && argv_element[0] == '+'));
146 }
147
148 /* getopt_internal: the function that does all the dirty work */
149 static int
150 getopt_internal (int argc, char **argv, char *shortopts,
151 GETOPT_LONG_OPTION_T * longopts, int *longind, int only)
152 {
153 GETOPT_ORDERING_T ordering = PERMUTE;
154 static size_t optwhere = 0;
155 size_t permute_from = 0;
156 int num_nonopts = 0;
157 int optindex = 0;
158 size_t match_chars = 0;
159 char *possible_arg = NULL;
160 int longopt_match = -1;
161 int has_arg = -1;
162 char *cp = NULL;
163 int arg_next = 0;
164
165 /* first, deal with silly parameters and easy stuff */
166 if (argc == 0 || argv == NULL || (shortopts == NULL && longopts == NULL))
167 return (optopt = '?');
168 if (optind >= argc || argv[optind] == NULL)
169 return EOF;
170 if (strcmp (argv[optind], "--") == 0)
171 {
172 optind++;
173 return EOF;
174 }
175 /* if this is our first time through */
176 if (optind == 0)
177 optind = optwhere = 1;
178
179 /* define ordering */
180 if (shortopts != NULL && (*shortopts == '-' || *shortopts == '+'))
181 {
182 ordering = (*shortopts == '-') ? RETURN_IN_ORDER : REQUIRE_ORDER;
183 shortopts++;
184 }
185 else
186 ordering = (getenv ("POSIXLY_CORRECT") != NULL) ? REQUIRE_ORDER : PERMUTE;
187
188 /*
189 * based on ordering, find our next option, if we're at the beginning of
190 * one
191 */
192 if (optwhere == 1)
193 {
194 switch (ordering)
195 {
196 case PERMUTE:
197 permute_from = optind;
198 num_nonopts = 0;
199 while (!is_option (argv[optind], only))
200 {
201 optind++;
202 num_nonopts++;
203 }
204 if (argv[optind] == NULL)
205 {
206 /* no more options */
207 optind = permute_from;
208 return EOF;
209 }
210 else if (strcmp (argv[optind], "--") == 0)
211 {
212 /* no more options, but have to get `--' out of the way */
213 permute (argv + permute_from, num_nonopts, 1);
214 optind = permute_from + 1;
215 return EOF;
216 }
217 break;
218 case RETURN_IN_ORDER:
219 if (!is_option (argv[optind], only))
220 {
221 optarg = argv[optind++];
222 return (optopt = 1);
223 }
224 break;
225 case REQUIRE_ORDER:
226 if (!is_option (argv[optind], only))
227 return EOF;
228 break;
229 }
230 }
231 /* we've got an option, so parse it */
232
233 /* first, is it a long option? */
234 if (longopts != NULL
235 && (memcmp (argv[optind], "--", 2) == 0
236 || (only && argv[optind][0] == '+')) && optwhere == 1)
237 {
238 /* handle long options */
239 if (memcmp (argv[optind], "--", 2) == 0)
240 optwhere = 2;
241 longopt_match = -1;
242 possible_arg = strchr (argv[optind] + optwhere, '=');
243 if (possible_arg == NULL)
244 {
245 /* no =, so next argv might be arg */
246 match_chars = strlen (argv[optind]);
247 possible_arg = argv[optind] + match_chars;
248 match_chars = match_chars - optwhere;
249 }
250 else
251 match_chars = (possible_arg - argv[optind]) - optwhere;
252 for (optindex = 0; longopts[optindex].name != NULL; optindex++)
253 {
254 if (memcmp (argv[optind] + optwhere,
255 longopts[optindex].name, match_chars) == 0)
256 {
257 /* do we have an exact match? */
258 if (match_chars == strlen (longopts[optindex].name))
259 {
260 longopt_match = optindex;
261 break;
262 }
263 /* do any characters match? */
264 else
265 {
266 if (longopt_match < 0)
267 longopt_match = optindex;
268 else
269 {
270 /* we have ambiguous options */
271 if (opterr)
272 fprintf (stderr, "%s: option `%s' is ambiguous "
273 "(could be `--%s' or `--%s')\n",
274 argv[0],
275 argv[optind],
276 longopts[longopt_match].name,
277 longopts[optindex].name);
278 return (optopt = '?');
279 }
280 }
281 }
282 }
283 if (longopt_match >= 0)
284 has_arg = longopts[longopt_match].has_arg;
285 }
286 /* if we didn't find a long option, is it a short option? */
287 if (longopt_match < 0 && shortopts != NULL)
288 {
289 cp = strchr (shortopts, argv[optind][optwhere]);
290 if (cp == NULL)
291 {
292 /* couldn't find option in shortopts */
293 if (opterr)
294 fprintf (stderr,
295 "%s: invalid option -- `-%c'\n",
296 argv[0], argv[optind][optwhere]);
297 optwhere++;
298 if (argv[optind][optwhere] == '\0')
299 {
300 optind++;
301 optwhere = 1;
302 }
303 return (optopt = '?');
304 }
305 has_arg = ((cp[1] == ':')
306 ? ((cp[2] == ':') ? OPTIONAL_ARG : required_argument) : no_argu ment);
307 possible_arg = argv[optind] + optwhere + 1;
308 optopt = *cp;
309 }
310 /* get argument and reset optwhere */
311 arg_next = 0;
312 switch (has_arg)
313 {
314 case OPTIONAL_ARG:
315 if (*possible_arg == '=')
316 possible_arg++;
317 if (*possible_arg != '\0')
318 {
319 optarg = possible_arg;
320 optwhere = 1;
321 }
322 else
323 optarg = NULL;
324 break;
325 case required_argument:
326 if (*possible_arg == '=')
327 possible_arg++;
328 if (*possible_arg != '\0')
329 {
330 optarg = possible_arg;
331 optwhere = 1;
332 }
333 else if (optind + 1 >= argc)
334 {
335 if (opterr)
336 {
337 fprintf (stderr, "%s: argument required for option `", argv[0]);
338 if (longopt_match >= 0)
339 fprintf (stderr, "--%s'\n", longopts[longopt_match].name);
340 else
341 fprintf (stderr, "-%c'\n", *cp);
342 }
343 optind++;
344 return (optopt = ':');
345 }
346 else
347 {
348 optarg = argv[optind + 1];
349 arg_next = 1;
350 optwhere = 1;
351 }
352 break;
353 case no_argument:
354 if (longopt_match < 0)
355 {
356 optwhere++;
357 if (argv[optind][optwhere] == '\0')
358 optwhere = 1;
359 }
360 else
361 optwhere = 1;
362 optarg = NULL;
363 break;
364 }
365
366 /* do we have to permute or otherwise modify optind? */
367 if (ordering == PERMUTE && optwhere == 1 && num_nonopts != 0)
368 {
369 permute (argv + permute_from, num_nonopts, 1 + arg_next);
370 optind = permute_from + 1 + arg_next;
371 }
372 else if (optwhere == 1)
373 optind = optind + 1 + arg_next;
374
375 /* finally return */
376 if (longopt_match >= 0)
377 {
378 if (longind != NULL)
379 *longind = longopt_match;
380 if (longopts[longopt_match].flag != NULL)
381 {
382 *(longopts[longopt_match].flag) = longopts[longopt_match].val;
383 return 0;
384 }
385 else
386 return longopts[longopt_match].val;
387 }
388 else
389 return optopt;
390 }
391
392 int
393 getopt (int argc, char **argv, char *optstring)
394 {
395 return getopt_internal (argc, argv, optstring, NULL, NULL, 0);
396 }
397
398 int
399 getopt_long (int argc, char **argv, const char *shortopts,
400 const GETOPT_LONG_OPTION_T * longopts, int *longind)
401 {
402 return getopt_internal (argc, argv, (char*)shortopts, (GETOPT_LONG_OPTION_T*)l ongopts, longind, 0);
403 }
404
405 int
406 getopt_long_only (int argc, char **argv, const char *shortopts,
407 const GETOPT_LONG_OPTION_T * longopts, int *longind)
408 {
409 return getopt_internal (argc, argv, (char*)shortopts, (GETOPT_LONG_OPTION_T*)l ongopts, longind, 1);
410 }
411
412 /* end of file GETOPT.C */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698