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