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