00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _NO_PROTO
00027 # define _NO_PROTO
00028 #endif
00029
00030 #ifdef HAVE_CONFIG_H
00031 # include <config.h>
00032 #endif
00033
00034 #if !defined __STDC__ || !__STDC__
00035
00036
00037 # ifndef const
00038 # define const
00039 # endif
00040 #endif
00041
00042 #include <stdio.h>
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define GETOPT_INTERFACE_VERSION 2
00053 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
00054 # include <gnu-versions.h>
00055 # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
00056 # define ELIDE_CODE
00057 # endif
00058 #endif
00059
00060 #ifndef ELIDE_CODE
00061
00062
00063
00064
00065 #ifdef __GNU_LIBRARY__
00066
00067
00068 # include <stdlib.h>
00069 # include <unistd.h>
00070 #endif
00071
00072 #ifdef VMS
00073 # include <unixlib.h>
00074 # if HAVE_STRING_H - 0
00075 # include <string.h>
00076 # endif
00077 #endif
00078
00079 #ifndef _
00080
00081 # if defined HAVE_LIBINTL_H || defined _LIBC
00082 # include <libintl.h>
00083 # ifndef _
00084 # define _(msgid) gettext (msgid)
00085 # endif
00086 # else
00087 # define _(msgid) (msgid)
00088 # endif
00089 #endif
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 #include "getopt.h"
00106
00107
00108
00109
00110
00111
00112
00113 char *optarg;
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 int optind = 1;
00129
00130
00131
00132
00133
00134 int __getopt_initialized;
00135
00136
00137
00138
00139
00140
00141
00142
00143 static char *nextchar;
00144
00145
00146
00147
00148 int opterr = 1;
00149
00150
00151
00152
00153
00154 int optopt = '?';
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 static enum
00186 {
00187 REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
00188 } ordering;
00189
00190
00191 static char *posixly_correct;
00192
00193 #ifdef __GNU_LIBRARY__
00194
00195
00196
00197
00198 # include <string.h>
00199 # define my_index strchr
00200 #else
00201
00202 # if HAVE_STRING_H
00203 # include <string.h>
00204 # else
00205 # include <strings.h>
00206 # endif
00207
00208
00209
00210
00211 #ifndef getenv
00212 extern char *getenv ();
00213 #endif
00214
00215 static char *
00216 my_index (str, chr)
00217 const char *str;
00218 int chr;
00219 {
00220 while (*str)
00221 {
00222 if (*str == chr)
00223 return (char *) str;
00224 str++;
00225 }
00226 return 0;
00227 }
00228
00229
00230
00231 #ifdef __GNUC__
00232
00233
00234 # if (!defined __STDC__ || !__STDC__) && !defined strlen
00235
00236
00237 extern int strlen (const char *);
00238 # endif
00239 #endif
00240
00241 #endif
00242
00243
00244
00245
00246
00247
00248
00249 static int first_nonopt;
00250 static int last_nonopt;
00251
00252 #ifdef _LIBC
00253
00254
00255
00256
00257 extern char *__getopt_nonoption_flags;
00258
00259 static int nonoption_flags_max_len;
00260 static int nonoption_flags_len;
00261
00262 static int original_argc;
00263 static char *const *original_argv;
00264
00265
00266
00267
00268 static void
00269 __attribute__ ((unused))
00270 store_args_and_env (int argc, char *const *argv)
00271 {
00272
00273
00274 original_argc = argc;
00275 original_argv = argv;
00276 }
00277 # ifdef text_set_element
00278 text_set_element (__libc_subinit, store_args_and_env);
00279 # endif
00280
00281 # define SWAP_FLAGS(ch1, ch2) \
00282 if (nonoption_flags_len > 0) \
00283 { \
00284 char __tmp = __getopt_nonoption_flags[ch1]; \
00285 __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
00286 __getopt_nonoption_flags[ch2] = __tmp; \
00287 }
00288 #else
00289 # define SWAP_FLAGS(ch1, ch2)
00290 #endif
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 #if defined __STDC__ && __STDC__
00302 static void exchange (char **);
00303 #endif
00304
00305 static void
00306 exchange (argv)
00307 char **argv;
00308 {
00309 int bottom = first_nonopt;
00310 int middle = last_nonopt;
00311 int top = optind;
00312 char *tem;
00313
00314
00315
00316
00317
00318
00319 #ifdef _LIBC
00320
00321
00322
00323 if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
00324 {
00325
00326
00327 char *new_str = malloc (top + 1);
00328 if (new_str == NULL)
00329 nonoption_flags_len = nonoption_flags_max_len = 0;
00330 else
00331 {
00332 memset (__mempcpy (new_str, __getopt_nonoption_flags,
00333 nonoption_flags_max_len),
00334 '\0', top + 1 - nonoption_flags_max_len);
00335 nonoption_flags_max_len = top + 1;
00336 __getopt_nonoption_flags = new_str;
00337 }
00338 }
00339 #endif
00340
00341 while (top > middle && middle > bottom)
00342 {
00343 if (top - middle > middle - bottom)
00344 {
00345
00346 int len = middle - bottom;
00347 register int i;
00348
00349
00350 for (i = 0; i < len; i++)
00351 {
00352 tem = argv[bottom + i];
00353 argv[bottom + i] = argv[top - (middle - bottom) + i];
00354 argv[top - (middle - bottom) + i] = tem;
00355 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
00356 }
00357
00358 top -= len;
00359 }
00360 else
00361 {
00362
00363 int len = top - middle;
00364 register int i;
00365
00366
00367 for (i = 0; i < len; i++)
00368 {
00369 tem = argv[bottom + i];
00370 argv[bottom + i] = argv[middle + i];
00371 argv[middle + i] = tem;
00372 SWAP_FLAGS (bottom + i, middle + i);
00373 }
00374
00375 bottom += len;
00376 }
00377 }
00378
00379
00380
00381 first_nonopt += (optind - last_nonopt);
00382 last_nonopt = optind;
00383 }
00384
00385
00386
00387 #if defined __STDC__ && __STDC__
00388 static const char *_getopt_initialize (int, char *const *, const char *);
00389 #endif
00390 static const char *
00391 _getopt_initialize (argc, argv, optstring)
00392 int argc;
00393 char *const *argv;
00394 const char *optstring;
00395 {
00396
00397
00398
00399
00400 first_nonopt = last_nonopt = optind;
00401
00402 nextchar = NULL;
00403
00404 posixly_correct = getenv ("POSIXLY_CORRECT");
00405
00406
00407
00408 if (optstring[0] == '-')
00409 {
00410 ordering = RETURN_IN_ORDER;
00411 ++optstring;
00412 }
00413 else if (optstring[0] == '+')
00414 {
00415 ordering = REQUIRE_ORDER;
00416 ++optstring;
00417 }
00418 else if (posixly_correct != NULL)
00419 ordering = REQUIRE_ORDER;
00420 else
00421 ordering = PERMUTE;
00422
00423 #ifdef _LIBC
00424 if (posixly_correct == NULL
00425 && argc == original_argc && argv == original_argv)
00426 {
00427 if (nonoption_flags_max_len == 0)
00428 {
00429 if (__getopt_nonoption_flags == NULL
00430 || __getopt_nonoption_flags[0] == '\0')
00431 nonoption_flags_max_len = -1;
00432 else
00433 {
00434 const char *orig_str = __getopt_nonoption_flags;
00435 int len = nonoption_flags_max_len = strlen (orig_str);
00436 if (nonoption_flags_max_len < argc)
00437 nonoption_flags_max_len = argc;
00438 __getopt_nonoption_flags =
00439 (char *) malloc (nonoption_flags_max_len);
00440 if (__getopt_nonoption_flags == NULL)
00441 nonoption_flags_max_len = -1;
00442 else
00443 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
00444 '\0', nonoption_flags_max_len - len);
00445 }
00446 }
00447 nonoption_flags_len = nonoption_flags_max_len;
00448 }
00449 else
00450 nonoption_flags_len = 0;
00451 #endif
00452
00453 return optstring;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 int
00513 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
00514 int argc;
00515 char *const *argv;
00516 const char *optstring;
00517 const struct option *longopts;
00518 int *longind;
00519 int long_only;
00520 {
00521 int print_errors = opterr;
00522 if (optstring[0] == ':')
00523 print_errors = 0;
00524
00525 if (argc < 1)
00526 return -1;
00527
00528 optarg = NULL;
00529
00530 if (optind == 0 || !__getopt_initialized)
00531 {
00532 if (optind == 0)
00533 optind = 1;
00534 optstring = _getopt_initialize (argc, argv, optstring);
00535 __getopt_initialized = 1;
00536 }
00537
00538
00539
00540
00541
00542 #ifdef _LIBC
00543 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
00544 || (optind < nonoption_flags_len \
00545 && __getopt_nonoption_flags[optind] == '1'))
00546 #else
00547 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
00548 #endif
00549
00550 if (nextchar == NULL || *nextchar == '\0')
00551 {
00552
00553
00554
00555
00556 if (last_nonopt > optind)
00557 last_nonopt = optind;
00558 if (first_nonopt > optind)
00559 first_nonopt = optind;
00560
00561 if (ordering == PERMUTE)
00562 {
00563
00564
00565
00566 if (first_nonopt != last_nonopt && last_nonopt != optind)
00567 exchange ((char **) argv);
00568 else if (last_nonopt != optind)
00569 first_nonopt = optind;
00570
00571
00572
00573
00574 while (optind < argc && NONOPTION_P)
00575 optind++;
00576 last_nonopt = optind;
00577 }
00578
00579
00580
00581
00582
00583
00584 if (optind != argc && !strcmp (argv[optind], "--"))
00585 {
00586 optind++;
00587
00588 if (first_nonopt != last_nonopt && last_nonopt != optind)
00589 exchange ((char **) argv);
00590 else if (first_nonopt == last_nonopt)
00591 first_nonopt = optind;
00592 last_nonopt = argc;
00593
00594 optind = argc;
00595 }
00596
00597
00598
00599
00600 if (optind == argc)
00601 {
00602
00603
00604 if (first_nonopt != last_nonopt)
00605 optind = first_nonopt;
00606 return -1;
00607 }
00608
00609
00610
00611
00612 if (NONOPTION_P)
00613 {
00614 if (ordering == REQUIRE_ORDER)
00615 return -1;
00616 optarg = argv[optind++];
00617 return 1;
00618 }
00619
00620
00621
00622
00623 nextchar = (argv[optind] + 1
00624 + (longopts != NULL && argv[optind][1] == '-'));
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 if (longopts != NULL
00643 && (argv[optind][1] == '-'
00644 || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
00645 {
00646 char *nameend;
00647 const struct option *p;
00648 const struct option *pfound = NULL;
00649 int exact = 0;
00650 int ambig = 0;
00651 int indfound = -1;
00652 int option_index;
00653
00654 for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
00655 ;
00656
00657
00658
00659 for (p = longopts, option_index = 0; p->name; p++, option_index++)
00660 if (!strncmp (p->name, nextchar, nameend - nextchar))
00661 {
00662 if ((unsigned int) (nameend - nextchar)
00663 == (unsigned int) strlen (p->name))
00664 {
00665
00666 pfound = p;
00667 indfound = option_index;
00668 exact = 1;
00669 break;
00670 }
00671 else if (pfound == NULL)
00672 {
00673
00674 pfound = p;
00675 indfound = option_index;
00676 }
00677 else if (long_only
00678 || pfound->has_arg != p->has_arg
00679 || pfound->flag != p->flag
00680 || pfound->val != p->val)
00681
00682 ambig = 1;
00683 }
00684
00685 if (ambig && !exact)
00686 {
00687 if (print_errors)
00688 fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
00689 argv[0], argv[optind]);
00690 nextchar += strlen (nextchar);
00691 optind++;
00692 optopt = 0;
00693 return '?';
00694 }
00695
00696 if (pfound != NULL)
00697 {
00698 option_index = indfound;
00699 optind++;
00700 if (*nameend)
00701 {
00702
00703
00704 if (pfound->has_arg)
00705 optarg = nameend + 1;
00706 else
00707 {
00708 if (print_errors)
00709 {
00710 if (argv[optind - 1][1] == '-')
00711
00712 fprintf (stderr,
00713 _("%s: option `--%s' doesn't allow an argument\n"),
00714 argv[0], pfound->name);
00715 else
00716
00717 fprintf (stderr,
00718 _("%s: option `%c%s' doesn't allow an argument\n"),
00719 argv[0], argv[optind - 1][0], pfound->name);
00720 }
00721
00722 nextchar += strlen (nextchar);
00723
00724 optopt = pfound->val;
00725 return '?';
00726 }
00727 }
00728 else if (pfound->has_arg == 1)
00729 {
00730 if (optind < argc)
00731 optarg = argv[optind++];
00732 else
00733 {
00734 if (print_errors)
00735 fprintf (stderr,
00736 _("%s: option `%s' requires an argument\n"),
00737 argv[0], argv[optind - 1]);
00738 nextchar += strlen (nextchar);
00739 optopt = pfound->val;
00740 return optstring[0] == ':' ? ':' : '?';
00741 }
00742 }
00743 nextchar += strlen (nextchar);
00744 if (longind != NULL)
00745 *longind = option_index;
00746 if (pfound->flag)
00747 {
00748 *(pfound->flag) = pfound->val;
00749 return 0;
00750 }
00751 return pfound->val;
00752 }
00753
00754
00755
00756
00757
00758 if (!long_only || argv[optind][1] == '-'
00759 || my_index (optstring, *nextchar) == NULL)
00760 {
00761 if (print_errors)
00762 {
00763 if (argv[optind][1] == '-')
00764
00765 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
00766 argv[0], nextchar);
00767 else
00768
00769 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
00770 argv[0], argv[optind][0], nextchar);
00771 }
00772 nextchar = (char *) "";
00773 optind++;
00774 optopt = 0;
00775 return '?';
00776 }
00777 }
00778
00779
00780
00781 {
00782 char c = *nextchar++;
00783 char *temp = my_index (optstring, c);
00784
00785
00786 if (*nextchar == '\0')
00787 ++optind;
00788
00789 if (temp == NULL || c == ':')
00790 {
00791 if (print_errors)
00792 {
00793 if (posixly_correct)
00794
00795 fprintf (stderr, _("%s: illegal option -- %c\n"),
00796 argv[0], c);
00797 else
00798 fprintf (stderr, _("%s: invalid option -- %c\n"),
00799 argv[0], c);
00800 }
00801 optopt = c;
00802 return '?';
00803 }
00804
00805 if (temp[0] == 'W' && temp[1] == ';')
00806 {
00807 char *nameend;
00808 const struct option *p;
00809 const struct option *pfound = NULL;
00810 int exact = 0;
00811 int ambig = 0;
00812 int indfound = 0;
00813 int option_index;
00814
00815
00816 if (*nextchar != '\0')
00817 {
00818 optarg = nextchar;
00819
00820
00821 optind++;
00822 }
00823 else if (optind == argc)
00824 {
00825 if (print_errors)
00826 {
00827
00828 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
00829 argv[0], c);
00830 }
00831 optopt = c;
00832 if (optstring[0] == ':')
00833 c = ':';
00834 else
00835 c = '?';
00836 return c;
00837 }
00838 else
00839
00840
00841 optarg = argv[optind++];
00842
00843
00844
00845
00846 for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
00847 ;
00848
00849
00850
00851 for (p = longopts, option_index = 0; p->name; p++, option_index++)
00852 if (!strncmp (p->name, nextchar, nameend - nextchar))
00853 {
00854 if ((unsigned int) (nameend - nextchar) == strlen (p->name))
00855 {
00856
00857 pfound = p;
00858 indfound = option_index;
00859 exact = 1;
00860 break;
00861 }
00862 else if (pfound == NULL)
00863 {
00864
00865 pfound = p;
00866 indfound = option_index;
00867 }
00868 else
00869
00870 ambig = 1;
00871 }
00872 if (ambig && !exact)
00873 {
00874 if (print_errors)
00875 fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
00876 argv[0], argv[optind]);
00877 nextchar += strlen (nextchar);
00878 optind++;
00879 return '?';
00880 }
00881 if (pfound != NULL)
00882 {
00883 option_index = indfound;
00884 if (*nameend)
00885 {
00886
00887
00888 if (pfound->has_arg)
00889 optarg = nameend + 1;
00890 else
00891 {
00892 if (print_errors)
00893 fprintf (stderr, _("%s: option `-W %s' doesn't allow an argument\n"),
00894 argv[0], pfound->name);
00895
00896 nextchar += strlen (nextchar);
00897 return '?';
00898 }
00899 }
00900 else if (pfound->has_arg == 1)
00901 {
00902 if (optind < argc)
00903 optarg = argv[optind++];
00904 else
00905 {
00906 if (print_errors)
00907 fprintf (stderr,
00908 _("%s: option `%s' requires an argument\n"),
00909 argv[0], argv[optind - 1]);
00910 nextchar += strlen (nextchar);
00911 return optstring[0] == ':' ? ':' : '?';
00912 }
00913 }
00914 nextchar += strlen (nextchar);
00915 if (longind != NULL)
00916 *longind = option_index;
00917 if (pfound->flag)
00918 {
00919 *(pfound->flag) = pfound->val;
00920 return 0;
00921 }
00922 return pfound->val;
00923 }
00924 nextchar = NULL;
00925 return 'W';
00926 }
00927 if (temp[1] == ':')
00928 {
00929 if (temp[2] == ':')
00930 {
00931
00932 if (*nextchar != '\0')
00933 {
00934 optarg = nextchar;
00935 optind++;
00936 }
00937 else
00938 optarg = NULL;
00939 nextchar = NULL;
00940 }
00941 else
00942 {
00943
00944 if (*nextchar != '\0')
00945 {
00946 optarg = nextchar;
00947
00948
00949 optind++;
00950 }
00951 else if (optind == argc)
00952 {
00953 if (print_errors)
00954 {
00955
00956 fprintf (stderr,
00957 _("%s: option requires an argument -- %c\n"),
00958 argv[0], c);
00959 }
00960 optopt = c;
00961 if (optstring[0] == ':')
00962 c = ':';
00963 else
00964 c = '?';
00965 }
00966 else
00967
00968
00969 optarg = argv[optind++];
00970 nextchar = NULL;
00971 }
00972 }
00973 return c;
00974 }
00975 }
00976
00977 int
00978 getopt (argc, argv, optstring)
00979 int argc;
00980 char *const *argv;
00981 const char *optstring;
00982 {
00983 return _getopt_internal (argc, argv, optstring,
00984 (const struct option *) 0,
00985 (int *) 0,
00986 0);
00987 }
00988
00989 #endif
00990
00991 #ifdef TEST
00992
00993
00994
00995
00996 int
00997 main (argc, argv)
00998 int argc;
00999 char **argv;
01000 {
01001 int c;
01002 int digit_optind = 0;
01003
01004 while (1)
01005 {
01006 int this_option_optind = optind ? optind : 1;
01007
01008 c = getopt (argc, argv, "abc:d:0123456789");
01009 if (c == -1)
01010 break;
01011
01012 switch (c)
01013 {
01014 case '0':
01015 case '1':
01016 case '2':
01017 case '3':
01018 case '4':
01019 case '5':
01020 case '6':
01021 case '7':
01022 case '8':
01023 case '9':
01024 if (digit_optind != 0 && digit_optind != this_option_optind)
01025 printf ("digits occur in two different argv-elements.\n");
01026 digit_optind = this_option_optind;
01027 printf ("option %c\n", c);
01028 break;
01029
01030 case 'a':
01031 printf ("option a\n");
01032 break;
01033
01034 case 'b':
01035 printf ("option b\n");
01036 break;
01037
01038 case 'c':
01039 printf ("option c with value `%s'\n", optarg);
01040 break;
01041
01042 case '?':
01043 break;
01044
01045 default:
01046 printf ("?? getopt returned character code 0%o ??\n", c);
01047 }
01048 }
01049
01050 if (optind < argc)
01051 {
01052 printf ("non-option ARGV-elements: ");
01053 while (optind < argc)
01054 printf ("%s ", argv[optind++]);
01055 printf ("\n");
01056 }
01057
01058 exit (0);
01059 }
01060
01061 #endif