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