This source file includes following definitions.
- exchange
- process_long_option
- _getopt_initialize
- _getopt_internal_r
- _getopt_internal
- GETOPT_ENTRY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #ifndef _LIBC
21 # include <config.h>
22 #endif
23
24 #include "getopt.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30
31 #ifdef _LIBC
32
33
34
35
36
37
38
39 # include <libintl.h>
40 # define fprintf __fxprintf_nocancel
41 # define flockfile(fp) _IO_flockfile (fp)
42 # define funlockfile(fp) _IO_funlockfile (fp)
43 #else
44 # include "gettext.h"
45 # define _(msgid) gettext (msgid)
46
47
48 # if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \
49 || (defined _WIN32 && ! defined __CYGWIN__))
50 # define flockfile(fp)
51 # define funlockfile(fp)
52 # endif
53
54 # define __libc_use_alloca(size) 0
55 # undef alloca
56 # define alloca(size) (abort (), (void *)0)
57 #endif
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 #include "getopt_int.h"
82
83
84
85
86
87
88
89 char *optarg;
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 int optind = 1;
105
106
107
108
109 int opterr = 1;
110
111
112
113
114
115 int optopt = '?';
116
117
118
119 static struct _getopt_data getopt_data;
120
121
122
123
124
125
126
127
128
129
130 static void
131 exchange (char **argv, struct _getopt_data *d)
132 {
133 int bottom = d->__first_nonopt;
134 int middle = d->__last_nonopt;
135 int top = d->optind;
136 char *tem;
137
138
139
140
141
142
143 while (top > middle && middle > bottom)
144 {
145 if (top - middle > middle - bottom)
146 {
147
148 int len = middle - bottom;
149 int i;
150
151
152 for (i = 0; i < len; i++)
153 {
154 tem = argv[bottom + i];
155 argv[bottom + i] = argv[top - (middle - bottom) + i];
156 argv[top - (middle - bottom) + i] = tem;
157 }
158
159 top -= len;
160 }
161 else
162 {
163
164 int len = top - middle;
165 int i;
166
167
168 for (i = 0; i < len; i++)
169 {
170 tem = argv[bottom + i];
171 argv[bottom + i] = argv[middle + i];
172 argv[middle + i] = tem;
173 }
174
175 bottom += len;
176 }
177 }
178
179
180
181 d->__first_nonopt += (d->optind - d->__last_nonopt);
182 d->__last_nonopt = d->optind;
183 }
184
185
186
187
188
189
190
191
192
193 static int
194 process_long_option (int argc, char **argv, const char *optstring,
195 const struct option *longopts, int *longind,
196 int long_only, struct _getopt_data *d,
197 int print_errors, const char *prefix)
198 {
199 char *nameend;
200 size_t namelen;
201 const struct option *p;
202 const struct option *pfound = NULL;
203 int n_options;
204 int option_index;
205
206 for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
207 ;
208 namelen = nameend - d->__nextchar;
209
210
211
212 for (p = longopts, n_options = 0; p->name; p++, n_options++)
213 if (!strncmp (p->name, d->__nextchar, namelen)
214 && namelen == strlen (p->name))
215 {
216
217 pfound = p;
218 option_index = n_options;
219 break;
220 }
221
222 if (pfound == NULL)
223 {
224
225 unsigned char *ambig_set = NULL;
226 int ambig_malloced = 0;
227 int ambig_fallback = 0;
228 int indfound = -1;
229
230 for (p = longopts, option_index = 0; p->name; p++, option_index++)
231 if (!strncmp (p->name, d->__nextchar, namelen))
232 {
233 if (pfound == NULL)
234 {
235
236 pfound = p;
237 indfound = option_index;
238 }
239 else if (long_only
240 || pfound->has_arg != p->has_arg
241 || pfound->flag != p->flag
242 || pfound->val != p->val)
243 {
244
245 if (!ambig_fallback)
246 {
247 if (!print_errors)
248
249
250 ambig_fallback = 1;
251 else if (!ambig_set)
252 {
253 if (__libc_use_alloca (n_options))
254 ambig_set = alloca (n_options);
255 else if ((ambig_set = malloc (n_options)) == NULL)
256
257 ambig_fallback = 1;
258 else
259 ambig_malloced = 1;
260
261 if (ambig_set)
262 {
263 memset (ambig_set, 0, n_options);
264 ambig_set[indfound] = 1;
265 }
266 }
267 if (ambig_set)
268 ambig_set[option_index] = 1;
269 }
270 }
271 }
272
273 if (ambig_set || ambig_fallback)
274 {
275 if (print_errors)
276 {
277 if (ambig_fallback)
278 fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"),
279 argv[0], prefix, d->__nextchar);
280 else
281 {
282 flockfile (stderr);
283 fprintf (stderr,
284 _("%s: option '%s%s' is ambiguous; possibilities:"),
285 argv[0], prefix, d->__nextchar);
286
287 for (option_index = 0; option_index < n_options; option_index++)
288 if (ambig_set[option_index])
289 fprintf (stderr, " '%s%s'",
290 prefix, longopts[option_index].name);
291
292
293
294
295 fprintf (stderr, "\n");
296 funlockfile (stderr);
297 }
298 }
299 if (ambig_malloced)
300 free (ambig_set);
301 d->__nextchar += strlen (d->__nextchar);
302 d->optind++;
303 d->optopt = 0;
304 return '?';
305 }
306
307 option_index = indfound;
308 }
309
310 if (pfound == NULL)
311 {
312
313
314
315 if (!long_only || argv[d->optind][1] == '-'
316 || strchr (optstring, *d->__nextchar) == NULL)
317 {
318 if (print_errors)
319 fprintf (stderr, _("%s: unrecognized option '%s%s'\n"),
320 argv[0], prefix, d->__nextchar);
321
322 d->__nextchar = NULL;
323 d->optind++;
324 d->optopt = 0;
325 return '?';
326 }
327
328
329 return -1;
330 }
331
332
333 d->optind++;
334 d->__nextchar = NULL;
335 if (*nameend)
336 {
337
338
339 if (pfound->has_arg)
340 d->optarg = nameend + 1;
341 else
342 {
343 if (print_errors)
344 fprintf (stderr,
345 _("%s: option '%s%s' doesn't allow an argument\n"),
346 argv[0], prefix, pfound->name);
347
348 d->optopt = pfound->val;
349 return '?';
350 }
351 }
352 else if (pfound->has_arg == 1)
353 {
354 if (d->optind < argc)
355 d->optarg = argv[d->optind++];
356 else
357 {
358 if (print_errors)
359 fprintf (stderr,
360 _("%s: option '%s%s' requires an argument\n"),
361 argv[0], prefix, pfound->name);
362
363 d->optopt = pfound->val;
364 return optstring[0] == ':' ? ':' : '?';
365 }
366 }
367
368 if (longind != NULL)
369 *longind = option_index;
370 if (pfound->flag)
371 {
372 *(pfound->flag) = pfound->val;
373 return 0;
374 }
375 return pfound->val;
376 }
377
378
379
380 static const char *
381 _getopt_initialize (_GL_UNUSED int argc,
382 _GL_UNUSED char **argv, const char *optstring,
383 struct _getopt_data *d, int posixly_correct)
384 {
385
386
387
388 if (d->optind == 0)
389 d->optind = 1;
390
391 d->__first_nonopt = d->__last_nonopt = d->optind;
392 d->__nextchar = NULL;
393
394
395 if (optstring[0] == '-')
396 {
397 d->__ordering = RETURN_IN_ORDER;
398 ++optstring;
399 }
400 else if (optstring[0] == '+')
401 {
402 d->__ordering = REQUIRE_ORDER;
403 ++optstring;
404 }
405 else if (posixly_correct || !!getenv ("POSIXLY_CORRECT"))
406 d->__ordering = REQUIRE_ORDER;
407 else
408 d->__ordering = PERMUTE;
409
410 d->__initialized = 1;
411 return optstring;
412 }
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470 int
471 _getopt_internal_r (int argc, char **argv, const char *optstring,
472 const struct option *longopts, int *longind,
473 int long_only, struct _getopt_data *d, int posixly_correct)
474 {
475 int print_errors = d->opterr;
476
477 if (argc < 1)
478 return -1;
479
480 d->optarg = NULL;
481
482 if (d->optind == 0 || !d->__initialized)
483 optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct);
484 else if (optstring[0] == '-' || optstring[0] == '+')
485 optstring++;
486
487 if (optstring[0] == ':')
488 print_errors = 0;
489
490
491 #define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
492
493 if (d->__nextchar == NULL || *d->__nextchar == '\0')
494 {
495
496
497
498
499 if (d->__last_nonopt > d->optind)
500 d->__last_nonopt = d->optind;
501 if (d->__first_nonopt > d->optind)
502 d->__first_nonopt = d->optind;
503
504 if (d->__ordering == PERMUTE)
505 {
506
507
508
509 if (d->__first_nonopt != d->__last_nonopt
510 && d->__last_nonopt != d->optind)
511 exchange (argv, d);
512 else if (d->__last_nonopt != d->optind)
513 d->__first_nonopt = d->optind;
514
515
516
517
518 while (d->optind < argc && NONOPTION_P)
519 d->optind++;
520 d->__last_nonopt = d->optind;
521 }
522
523
524
525
526
527
528 if (d->optind != argc && !strcmp (argv[d->optind], "--"))
529 {
530 d->optind++;
531
532 if (d->__first_nonopt != d->__last_nonopt
533 && d->__last_nonopt != d->optind)
534 exchange (argv, d);
535 else if (d->__first_nonopt == d->__last_nonopt)
536 d->__first_nonopt = d->optind;
537 d->__last_nonopt = argc;
538
539 d->optind = argc;
540 }
541
542
543
544
545 if (d->optind == argc)
546 {
547
548
549 if (d->__first_nonopt != d->__last_nonopt)
550 d->optind = d->__first_nonopt;
551 return -1;
552 }
553
554
555
556
557 if (NONOPTION_P)
558 {
559 if (d->__ordering == REQUIRE_ORDER)
560 return -1;
561 d->optarg = argv[d->optind++];
562 return 1;
563 }
564
565
566
567 if (longopts)
568 {
569 if (argv[d->optind][1] == '-')
570 {
571
572
573 d->__nextchar = argv[d->optind] + 2;
574 return process_long_option (argc, argv, optstring, longopts,
575 longind, long_only, d,
576 print_errors, "--");
577 }
578
579
580
581
582
583
584
585
586
587
588
589
590
591 if (long_only && (argv[d->optind][2]
592 || !strchr (optstring, argv[d->optind][1])))
593 {
594 int code;
595 d->__nextchar = argv[d->optind] + 1;
596 code = process_long_option (argc, argv, optstring, longopts,
597 longind, long_only, d,
598 print_errors, "-");
599 if (code != -1)
600 return code;
601 }
602 }
603
604
605 d->__nextchar = argv[d->optind] + 1;
606 }
607
608
609
610 {
611 char c = *d->__nextchar++;
612 const char *temp = strchr (optstring, c);
613
614
615 if (*d->__nextchar == '\0')
616 ++d->optind;
617
618 if (temp == NULL || c == ':' || c == ';')
619 {
620 if (print_errors)
621 fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
622 d->optopt = c;
623 return '?';
624 }
625
626
627 if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL)
628 {
629
630 if (*d->__nextchar != '\0')
631 d->optarg = d->__nextchar;
632 else if (d->optind == argc)
633 {
634 if (print_errors)
635 fprintf (stderr,
636 _("%s: option requires an argument -- '%c'\n"),
637 argv[0], c);
638
639 d->optopt = c;
640 if (optstring[0] == ':')
641 c = ':';
642 else
643 c = '?';
644 return c;
645 }
646 else
647 d->optarg = argv[d->optind];
648
649 d->__nextchar = d->optarg;
650 d->optarg = NULL;
651 return process_long_option (argc, argv, optstring, longopts, longind,
652 0 , d, print_errors, "-W ");
653 }
654 if (temp[1] == ':')
655 {
656 if (temp[2] == ':')
657 {
658
659 if (*d->__nextchar != '\0')
660 {
661 d->optarg = d->__nextchar;
662 d->optind++;
663 }
664 else
665 d->optarg = NULL;
666 d->__nextchar = NULL;
667 }
668 else
669 {
670
671 if (*d->__nextchar != '\0')
672 {
673 d->optarg = d->__nextchar;
674
675
676 d->optind++;
677 }
678 else if (d->optind == argc)
679 {
680 if (print_errors)
681 fprintf (stderr,
682 _("%s: option requires an argument -- '%c'\n"),
683 argv[0], c);
684
685 d->optopt = c;
686 if (optstring[0] == ':')
687 c = ':';
688 else
689 c = '?';
690 }
691 else
692
693
694 d->optarg = argv[d->optind++];
695 d->__nextchar = NULL;
696 }
697 }
698 return c;
699 }
700 }
701
702 int
703 _getopt_internal (int argc, char **argv, const char *optstring,
704 const struct option *longopts, int *longind, int long_only,
705 int posixly_correct)
706 {
707 int result;
708
709 getopt_data.optind = optind;
710 getopt_data.opterr = opterr;
711
712 result = _getopt_internal_r (argc, argv, optstring, longopts,
713 longind, long_only, &getopt_data,
714 posixly_correct);
715
716 optind = getopt_data.optind;
717 optarg = getopt_data.optarg;
718 optopt = getopt_data.optopt;
719
720 return result;
721 }
722
723
724
725
726
727 #define GETOPT_ENTRY(NAME, POSIXLY_CORRECT) \
728 int \
729 NAME (int argc, char *const *argv, const char *optstring) \
730 { \
731 return _getopt_internal (argc, (char **)argv, optstring, \
732 0, 0, 0, POSIXLY_CORRECT); \
733 }
734
735 #ifdef _LIBC
736 GETOPT_ENTRY(getopt, 0)
737 GETOPT_ENTRY(__posix_getopt, 1)
738 #else
739 GETOPT_ENTRY(getopt, 1)
740 #endif
741
742
743 #ifdef TEST
744
745
746
747
748 int
749 main (int argc, char **argv)
750 {
751 int c;
752 int digit_optind = 0;
753
754 while (1)
755 {
756 int this_option_optind = optind ? optind : 1;
757
758 c = getopt (argc, argv, "abc:d:0123456789");
759 if (c == -1)
760 break;
761
762 switch (c)
763 {
764 case '0':
765 case '1':
766 case '2':
767 case '3':
768 case '4':
769 case '5':
770 case '6':
771 case '7':
772 case '8':
773 case '9':
774 if (digit_optind != 0 && digit_optind != this_option_optind)
775 printf ("digits occur in two different argv-elements.\n");
776 digit_optind = this_option_optind;
777 printf ("option %c\n", c);
778 break;
779
780 case 'a':
781 printf ("option a\n");
782 break;
783
784 case 'b':
785 printf ("option b\n");
786 break;
787
788 case 'c':
789 printf ("option c with value '%s'\n", optarg);
790 break;
791
792 case '?':
793 break;
794
795 default:
796 printf ("?? getopt returned character code 0%o ??\n", c);
797 }
798 }
799
800 if (optind < argc)
801 {
802 printf ("non-option ARGV-elements: ");
803 while (optind < argc)
804 printf ("%s ", argv[optind++]);
805 printf ("\n");
806 }
807
808 exit (0);
809 }
810
811 #endif