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