1 /* Getopt for GNU.
2 NOTE: getopt is now part of the C library, so if you don't know what
3 "Keep this file name-space clean" means, talk to drepper@gnu.org
4 before changing it!
5 Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
6 Free Software Foundation, Inc.
7 This file is part of the GNU C Library.
8
9 The GNU C Library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 The GNU C Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with the GNU C Library; if not, write to the Free
21 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 02111-1307 USA. */
23
24 /* Excessive comments removed by Wojtek Kaniewski <wojtekka@irc.pl> */
25
26 #ifndef _NO_PROTO
27 # define _NO_PROTO
28 #endif
29
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
33
34 #if !defined __STDC__ || !__STDC__
35 # ifndef const
36 # define const
37 # endif
38 #endif
39
40 #include <stdio.h>
41
42 #define GETOPT_INTERFACE_VERSION 2
43 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
44 # include <gnu-versions.h>
45 # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
46 # define ELIDE_CODE
47 # endif
48 #endif
49
50 #ifndef ELIDE_CODE
51
52 #ifdef __GNU_LIBRARY__
53 # include <stdlib.h>
54 # include <unistd.h>
55 #endif /* GNU C library. */
56
57 #ifdef VMS
58 # include <unixlib.h>
59 # if HAVE_STRING_H - 0
60 # include <string.h>
61 # endif
62 #endif
63
64 #ifndef _
65 # if defined HAVE_LIBINTL_H || defined _LIBC
66 # include <libintl.h>
67 # ifndef _
68 # define _(msgid) gettext (msgid)
69 # endif
70 # else
71 # define _(msgid) (msgid)
72 # endif
73 #endif
74
75 #include "getopt.h"
76
77 char *optarg;
78
79 int optind = 1;
80
81 int __getopt_initialized;
82
83 static char *nextchar;
84
85 int opterr = 1;
86
87 int optopt = '?';
88
89 static enum
90 {
91 REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
92 } ordering;
93
94 static char *posixly_correct;
95
96 #ifdef __GNU_LIBRARY__
97 # include <string.h>
98 # define my_index strchr
99 #else
100
101 # if HAVE_STRING_H
102 # include <string.h>
103 # else
104 # include <strings.h>
105 # endif
106
107 #ifndef getenv
108 extern char *getenv ();
109 #endif
110
111 static char *
my_index(str,chr)112 my_index (str, chr)
113 const char *str;
114 int chr;
115 {
116 while (*str)
117 {
118 if (*str == chr)
119 return (char *) str;
120 str++;
121 }
122 return 0;
123 }
124
125 #ifdef __GNUC__
126 # if (!defined __STDC__ || !__STDC__) && !defined strlen
127 extern int strlen (const char *);
128 # endif /* not __STDC__ */
129 #endif /* __GNUC__ */
130
131 #endif /* not __GNU_LIBRARY__ */
132
133 static int first_nonopt;
134 static int last_nonopt;
135
136 #ifdef _LIBC
137 extern int __libc_argc;
138 extern char **__libc_argv;
139
140 # ifdef USE_NONOPTION_FLAGS
141 /* Defined in getopt_init.c */
142 extern char *__getopt_nonoption_flags;
143
144 static int nonoption_flags_max_len;
145 static int nonoption_flags_len;
146 # endif
147
148 # ifdef USE_NONOPTION_FLAGS
149 # define SWAP_FLAGS(ch1, ch2) \
150 if (nonoption_flags_len > 0) \
151 { \
152 char __tmp = __getopt_nonoption_flags[ch1]; \
153 __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
154 __getopt_nonoption_flags[ch2] = __tmp; \
155 }
156 # else
157 # define SWAP_FLAGS(ch1, ch2)
158 # endif
159 #else /* !_LIBC */
160 # define SWAP_FLAGS(ch1, ch2)
161 #endif /* _LIBC */
162
163 #if defined __STDC__ && __STDC__
164 static void exchange (char **);
165 #endif
166
167 static void
exchange(argv)168 exchange (argv)
169 char **argv;
170 {
171 int bottom = first_nonopt;
172 int middle = last_nonopt;
173 int top = optind;
174 char *tem;
175
176 #if defined _LIBC && defined USE_NONOPTION_FLAGS
177 if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
178 {
179 char *new_str = malloc (top + 1);
180 if (new_str == NULL)
181 nonoption_flags_len = nonoption_flags_max_len = 0;
182 else
183 {
184 memset (__mempcpy (new_str, __getopt_nonoption_flags,
185 nonoption_flags_max_len),
186 '\0', top + 1 - nonoption_flags_max_len);
187 nonoption_flags_max_len = top + 1;
188 __getopt_nonoption_flags = new_str;
189 }
190 }
191 #endif
192
193 while (top > middle && middle > bottom)
194 {
195 if (top - middle > middle - bottom)
196 {
197 /* Bottom segment is the short one. */
198 int len = middle - bottom;
199 register int i;
200
201 /* Swap it with the top part of the top segment. */
202 for (i = 0; i < len; i++)
203 {
204 tem = argv[bottom + i];
205 argv[bottom + i] = argv[top - (middle - bottom) + i];
206 argv[top - (middle - bottom) + i] = tem;
207 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
208 }
209 /* Exclude the moved bottom segment from further swapping. */
210 top -= len;
211 }
212 else
213 {
214 /* Top segment is the short one. */
215 int len = top - middle;
216 register int i;
217
218 /* Swap it with the bottom part of the bottom segment. */
219 for (i = 0; i < len; i++)
220 {
221 tem = argv[bottom + i];
222 argv[bottom + i] = argv[middle + i];
223 argv[middle + i] = tem;
224 SWAP_FLAGS (bottom + i, middle + i);
225 }
226 /* Exclude the moved top segment from further swapping. */
227 bottom += len;
228 }
229 }
230
231 /* Update records for the slots the non-options now occupy. */
232
233 first_nonopt += (optind - last_nonopt);
234 last_nonopt = optind;
235 }
236
237 /* Initialize the internal data when the first call is made. */
238
239 #if defined __STDC__ && __STDC__
240 static const char *_getopt_initialize (int, char *const *, const char *);
241 #endif
242 static const char *
_getopt_initialize(argc,argv,optstring)243 _getopt_initialize (argc, argv, optstring)
244 int argc;
245 char *const *argv;
246 const char *optstring;
247 {
248 first_nonopt = last_nonopt = optind;
249
250 nextchar = NULL;
251
252 posixly_correct = getenv ("POSIXLY_CORRECT");
253
254 if (optstring[0] == '-')
255 {
256 ordering = RETURN_IN_ORDER;
257 ++optstring;
258 }
259 else if (optstring[0] == '+')
260 {
261 ordering = REQUIRE_ORDER;
262 ++optstring;
263 }
264 else if (posixly_correct != NULL)
265 ordering = REQUIRE_ORDER;
266 else
267 ordering = PERMUTE;
268
269 #if defined _LIBC && defined USE_NONOPTION_FLAGS
270 if (posixly_correct == NULL
271 && argc == __libc_argc && argv == __libc_argv)
272 {
273 if (nonoption_flags_max_len == 0)
274 {
275 if (__getopt_nonoption_flags == NULL
276 || __getopt_nonoption_flags[0] == '\0')
277 nonoption_flags_max_len = -1;
278 else
279 {
280 const char *orig_str = __getopt_nonoption_flags;
281 int len = nonoption_flags_max_len = strlen (orig_str);
282 if (nonoption_flags_max_len < argc)
283 nonoption_flags_max_len = argc;
284 __getopt_nonoption_flags =
285 (char *) malloc (nonoption_flags_max_len);
286 if (__getopt_nonoption_flags == NULL)
287 nonoption_flags_max_len = -1;
288 else
289 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
290 '\0', nonoption_flags_max_len - len);
291 }
292 }
293 nonoption_flags_len = nonoption_flags_max_len;
294 }
295 else
296 nonoption_flags_len = 0;
297 #endif
298
299 return optstring;
300 }
301
302 int
_getopt_internal(argc,argv,optstring,longopts,longind,long_only)303 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
304 int argc;
305 char *const *argv;
306 const char *optstring;
307 const struct option *longopts;
308 int *longind;
309 int long_only;
310 {
311 int print_errors = opterr;
312 if (optstring[0] == ':')
313 print_errors = 0;
314
315 if (argc < 1)
316 return -1;
317
318 optarg = NULL;
319
320 if (optind == 0 || !__getopt_initialized)
321 {
322 if (optind == 0)
323 optind = 1; /* Don't scan ARGV[0], the program name. */
324 optstring = _getopt_initialize (argc, argv, optstring);
325 __getopt_initialized = 1;
326 }
327
328 #if defined _LIBC && defined USE_NONOPTION_FLAGS
329 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
330 || (optind < nonoption_flags_len \
331 && __getopt_nonoption_flags[optind] == '1'))
332 #else
333 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
334 #endif
335
336 if (nextchar == NULL || *nextchar == '\0')
337 {
338 if (last_nonopt > optind)
339 last_nonopt = optind;
340 if (first_nonopt > optind)
341 first_nonopt = optind;
342
343 if (ordering == PERMUTE)
344 {
345 if (first_nonopt != last_nonopt && last_nonopt != optind)
346 exchange ((char **) argv);
347 else if (last_nonopt != optind)
348 first_nonopt = optind;
349
350 while (optind < argc && NONOPTION_P)
351 optind++;
352 last_nonopt = optind;
353 }
354
355 if (optind != argc && !strcmp (argv[optind], "--"))
356 {
357 optind++;
358
359 if (first_nonopt != last_nonopt && last_nonopt != optind)
360 exchange ((char **) argv);
361 else if (first_nonopt == last_nonopt)
362 first_nonopt = optind;
363 last_nonopt = argc;
364
365 optind = argc;
366 }
367
368 if (optind == argc)
369 {
370 if (first_nonopt != last_nonopt)
371 optind = first_nonopt;
372 return -1;
373 }
374
375 if (NONOPTION_P)
376 {
377 if (ordering == REQUIRE_ORDER)
378 return -1;
379 optarg = argv[optind++];
380 return 1;
381 }
382
383 nextchar = (argv[optind] + 1
384 + (longopts != NULL && argv[optind][1] == '-'));
385 }
386 if (longopts != NULL
387 && (argv[optind][1] == '-'
388 || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
389 {
390 char *nameend;
391 const struct option *p;
392 const struct option *pfound = NULL;
393 int exact = 0;
394 int ambig = 0;
395 int indfound = -1;
396 int option_index;
397
398 for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
399 /* Do nothing. */ ;
400
401 for (p = longopts, option_index = 0; p->name; p++, option_index++)
402 if (!strncmp (p->name, nextchar, nameend - nextchar))
403 {
404 if ((unsigned int) (nameend - nextchar)
405 == (unsigned int) strlen (p->name))
406 {
407 /* Exact match found. */
408 pfound = p;
409 indfound = option_index;
410 exact = 1;
411 break;
412 }
413 else if (pfound == NULL)
414 {
415 /* First nonexact match found. */
416 pfound = p;
417 indfound = option_index;
418 }
419 else if (long_only
420 || pfound->has_arg != p->has_arg
421 || pfound->flag != p->flag
422 || pfound->val != p->val)
423 /* Second or later nonexact match found. */
424 ambig = 1;
425 }
426
427 if (ambig && !exact)
428 {
429 if (print_errors)
430 fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
431 argv[0], argv[optind]);
432 nextchar += strlen (nextchar);
433 optind++;
434 optopt = 0;
435 return '?';
436 }
437
438 if (pfound != NULL)
439 {
440 option_index = indfound;
441 optind++;
442 if (*nameend)
443 {
444 if (pfound->has_arg)
445 optarg = nameend + 1;
446 else
447 {
448 if (print_errors)
449 {
450 if (argv[optind - 1][1] == '-')
451 /* --option */
452 fprintf (stderr,
453 _("%s: option `--%s' doesn't allow an argument\n"),
454 argv[0], pfound->name);
455 else
456 /* +option or -option */
457 fprintf (stderr,
458 _("%s: option `%c%s' doesn't allow an argument\n"),
459 argv[0], argv[optind - 1][0], pfound->name);
460 }
461
462 nextchar += strlen (nextchar);
463
464 optopt = pfound->val;
465 return '?';
466 }
467 }
468 else if (pfound->has_arg == 1)
469 {
470 if (optind < argc)
471 optarg = argv[optind++];
472 else
473 {
474 if (print_errors)
475 fprintf (stderr,
476 _("%s: option `%s' requires an argument\n"),
477 argv[0], argv[optind - 1]);
478 nextchar += strlen (nextchar);
479 optopt = pfound->val;
480 return optstring[0] == ':' ? ':' : '?';
481 }
482 }
483 nextchar += strlen (nextchar);
484 if (longind != NULL)
485 *longind = option_index;
486 if (pfound->flag)
487 {
488 *(pfound->flag) = pfound->val;
489 return 0;
490 }
491 return pfound->val;
492 }
493
494 if (!long_only || argv[optind][1] == '-'
495 || my_index (optstring, *nextchar) == NULL)
496 {
497 if (print_errors)
498 {
499 if (argv[optind][1] == '-')
500 /* --option */
501 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
502 argv[0], nextchar);
503 else
504 /* +option or -option */
505 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
506 argv[0], argv[optind][0], nextchar);
507 }
508 nextchar = (char *) "";
509 optind++;
510 optopt = 0;
511 return '?';
512 }
513 }
514
515 {
516 char c = *nextchar++;
517 char *temp = my_index (optstring, c);
518
519 if (*nextchar == '\0')
520 ++optind;
521
522 if (temp == NULL || c == ':')
523 {
524 if (print_errors)
525 {
526 if (posixly_correct)
527 /* 1003.2 specifies the format of this message. */
528 fprintf (stderr, _("%s: illegal option -- %c\n"),
529 argv[0], c);
530 else
531 fprintf (stderr, _("%s: invalid option -- %c\n"),
532 argv[0], c);
533 }
534 optopt = c;
535 return '?';
536 }
537 /* Convenience. Treat POSIX -W foo same as long option --foo */
538 if (temp[0] == 'W' && temp[1] == ';')
539 {
540 char *nameend;
541 const struct option *p;
542 const struct option *pfound = NULL;
543 int exact = 0;
544 int ambig = 0;
545 int indfound = 0;
546 int option_index;
547
548 if (*nextchar != '\0')
549 {
550 optarg = nextchar;
551 optind++;
552 }
553 else if (optind == argc)
554 {
555 if (print_errors)
556 {
557 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
558 argv[0], c);
559 }
560 optopt = c;
561 if (optstring[0] == ':')
562 c = ':';
563 else
564 c = '?';
565 return c;
566 }
567 else
568 optarg = argv[optind++];
569
570 for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
571 /* Do nothing. */ ;
572
573 for (p = longopts, option_index = 0; p->name; p++, option_index++)
574 if (!strncmp (p->name, nextchar, nameend - nextchar))
575 {
576 if ((unsigned int) (nameend - nextchar) == strlen (p->name))
577 {
578 /* Exact match found. */
579 pfound = p;
580 indfound = option_index;
581 exact = 1;
582 break;
583 }
584 else if (pfound == NULL)
585 {
586 /* First nonexact match found. */
587 pfound = p;
588 indfound = option_index;
589 }
590 else
591 /* Second or later nonexact match found. */
592 ambig = 1;
593 }
594 if (ambig && !exact)
595 {
596 if (print_errors)
597 fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
598 argv[0], argv[optind]);
599 nextchar += strlen (nextchar);
600 optind++;
601 return '?';
602 }
603 if (pfound != NULL)
604 {
605 option_index = indfound;
606 if (*nameend)
607 {
608 if (pfound->has_arg)
609 optarg = nameend + 1;
610 else
611 {
612 if (print_errors)
613 fprintf (stderr, _("\
614 %s: option `-W %s' doesn't allow an argument\n"),
615 argv[0], pfound->name);
616
617 nextchar += strlen (nextchar);
618 return '?';
619 }
620 }
621 else if (pfound->has_arg == 1)
622 {
623 if (optind < argc)
624 optarg = argv[optind++];
625 else
626 {
627 if (print_errors)
628 fprintf (stderr,
629 _("%s: option `%s' requires an argument\n"),
630 argv[0], argv[optind - 1]);
631 nextchar += strlen (nextchar);
632 return optstring[0] == ':' ? ':' : '?';
633 }
634 }
635 nextchar += strlen (nextchar);
636 if (longind != NULL)
637 *longind = option_index;
638 if (pfound->flag)
639 {
640 *(pfound->flag) = pfound->val;
641 return 0;
642 }
643 return pfound->val;
644 }
645 nextchar = NULL;
646 return 'W'; /* Let the application handle it. */
647 }
648 if (temp[1] == ':')
649 {
650 if (temp[2] == ':')
651 {
652 /* This is an option that accepts an argument optionally. */
653 if (*nextchar != '\0')
654 {
655 optarg = nextchar;
656 optind++;
657 }
658 else
659 optarg = NULL;
660 nextchar = NULL;
661 }
662 else
663 {
664 if (*nextchar != '\0')
665 {
666 optarg = nextchar;
667 optind++;
668 }
669 else if (optind == argc)
670 {
671 if (print_errors)
672 {
673 fprintf (stderr,
674 _("%s: option requires an argument -- %c\n"),
675 argv[0], c);
676 }
677 optopt = c;
678 if (optstring[0] == ':')
679 c = ':';
680 else
681 c = '?';
682 }
683 else
684 /* We already incremented `optind' once;
685 increment it again when taking next ARGV-elt as argument. */
686 optarg = argv[optind++];
687 nextchar = NULL;
688 }
689 }
690 return c;
691 }
692 }
693
694 int
getopt(argc,argv,optstring)695 getopt (argc, argv, optstring)
696 int argc;
697 char *const *argv;
698 const char *optstring;
699 {
700 return _getopt_internal (argc, argv, optstring,
701 (const struct option *) 0,
702 (int *) 0,
703 0);
704 }
705
706 #endif /* Not ELIDE_CODE. */
707
708
709