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 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #if !__STDC__ && !defined(const) && IN_GCC
00033 #define const
00034 #endif
00035
00036
00037 #ifndef _NO_PROTO
00038 #define _NO_PROTO
00039 #endif
00040
00041 #include <stdio.h>
00042 #define HAVE_STRING_H
00043 #ifdef HAVE_STRING_H
00044 # include <string.h>
00045 #else
00046 # include <strings.h>
00047 #endif
00048
00049
00050 #ifdef WIN32
00051 #include <malloc.h>
00052 #endif
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
00063
00064
00065 #include <stdlib.h>
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #ifdef HAVE_NLS
00089 # define _(string) gettext (string)
00090 # ifdef HAVE_LIBINTL_H
00091 # include <libintl.h>
00092 # endif
00093 #else
00094 # define _(string) string
00095 #endif
00096
00097 #include "getopt.h"
00098
00099 const char *exec_name;
00100
00101
00102
00103
00104
00105
00106
00107 char *optarg = 0;
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 int optind = 0;
00123
00124
00125
00126
00127
00128
00129
00130
00131 static char *nextchar;
00132
00133
00134
00135
00136 int opterr = 1;
00137
00138
00139
00140
00141
00142 int optopt = '?';
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 static enum
00174 {
00175 REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
00176 } ordering;
00177
00178 #ifdef __GNU_LIBRARY__
00179
00180
00181
00182
00183 #include <string.h>
00184 #define my_index strchr
00185 #define my_bcopy(src, dst, n) memcpy ((dst), (src), (n))
00186 #else
00187
00188
00189
00190
00191 char *getenv ();
00192
00193 static char *
00194 my_index (const char *str, int chr)
00195 {
00196 while (*str)
00197 {
00198 if (*str == chr)
00199 return (char *) str;
00200 str++;
00201 }
00202 return 0;
00203 }
00204
00205 static void
00206 my_bcopy (const char *from, char *to, int size)
00207 {
00208 int i;
00209 for (i = 0; i < size; i++)
00210 to[i] = from[i];
00211 }
00212 #endif
00213
00214
00215
00216
00217
00218
00219
00220 static int first_nonopt;
00221 static int last_nonopt;
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 static void
00233 exchange (char **argv)
00234 {
00235 int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
00236 char **temp = (char **) alloca (nonopts_size);
00237
00238
00239
00240 my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
00241 my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
00242 (optind - last_nonopt) * sizeof (char *));
00243 my_bcopy ((char *) temp,
00244 (char *) &argv[first_nonopt + optind - last_nonopt],
00245 nonopts_size);
00246
00247
00248
00249 first_nonopt += (optind - last_nonopt);
00250 last_nonopt = optind;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 int
00310 _getopt_internal (int argc, char *const *argv, const char *optstring,
00311 const struct option *longopts, int *longind, int long_only)
00312 {
00313 int option_index;
00314
00315 optarg = 0;
00316
00317
00318
00319
00320
00321
00322 if (optind == 0)
00323 {
00324 first_nonopt = last_nonopt = optind = 1;
00325
00326 nextchar = NULL;
00327
00328
00329
00330 if (optstring[0] == '-')
00331 {
00332 ordering = RETURN_IN_ORDER;
00333 ++optstring;
00334 }
00335 else if (optstring[0] == '+')
00336 {
00337 ordering = REQUIRE_ORDER;
00338 ++optstring;
00339 }
00340 else if (getenv ("POSIXLY_CORRECT") != NULL)
00341 ordering = REQUIRE_ORDER;
00342 else
00343 ordering = PERMUTE;
00344 }
00345
00346 if (nextchar == NULL || *nextchar == '\0')
00347 {
00348 if (ordering == PERMUTE)
00349 {
00350
00351
00352
00353 if (first_nonopt != last_nonopt && last_nonopt != optind)
00354 exchange ((char **) argv);
00355 else if (last_nonopt != optind)
00356 first_nonopt = optind;
00357
00358
00359
00360
00361 while (optind < argc
00362 && (argv[optind][0] != '-' || argv[optind][1] == '\0')
00363 #ifdef GETOPT_COMPAT
00364 && (longopts == NULL
00365 || argv[optind][0] != '+' || argv[optind][1] == '\0')
00366 #endif
00367 )
00368 optind++;
00369 last_nonopt = optind;
00370 }
00371
00372
00373
00374
00375
00376
00377 if (optind != argc && !strcmp (argv[optind], "--"))
00378 {
00379 optind++;
00380
00381 if (first_nonopt != last_nonopt && last_nonopt != optind)
00382 exchange ((char **) argv);
00383 else if (first_nonopt == last_nonopt)
00384 first_nonopt = optind;
00385 last_nonopt = argc;
00386
00387 optind = argc;
00388 }
00389
00390
00391
00392
00393 if (optind == argc)
00394 {
00395
00396
00397 if (first_nonopt != last_nonopt)
00398 optind = first_nonopt;
00399 return EOF;
00400 }
00401
00402
00403
00404
00405 if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
00406 #ifdef GETOPT_COMPAT
00407 && (longopts == NULL
00408 || argv[optind][0] != '+' || argv[optind][1] == '\0')
00409 #endif
00410 )
00411 {
00412 if (ordering == REQUIRE_ORDER)
00413 return EOF;
00414 optarg = argv[optind++];
00415 return 1;
00416 }
00417
00418
00419
00420
00421 nextchar = (argv[optind] + 1
00422 + (longopts != NULL && argv[optind][1] == '-'));
00423 }
00424
00425 if (longopts != NULL
00426 && ((argv[optind][0] == '-'
00427 && (argv[optind][1] == '-' || long_only))
00428 #ifdef GETOPT_COMPAT
00429 || argv[optind][0] == '+'
00430 #endif
00431 ))
00432 {
00433 const struct option *p;
00434 char *s = nextchar;
00435 int exact = 0;
00436 int ambig = 0;
00437 const struct option *pfound = NULL;
00438 int indfound;
00439
00440 indfound = 0;
00441
00442 while (*s && *s != '=')
00443 s++;
00444
00445
00446 for (p = longopts, option_index = 0; p->name;
00447 p++, option_index++)
00448 if (!strncmp (p->name, nextchar, s - nextchar))
00449 {
00450 if (s - nextchar == strlen (p->name))
00451 {
00452
00453 pfound = p;
00454 indfound = option_index;
00455 exact = 1;
00456 break;
00457 }
00458 else if (pfound == NULL)
00459 {
00460
00461 pfound = p;
00462 indfound = option_index;
00463 }
00464 else
00465
00466 ambig = 1;
00467 }
00468
00469 if (ambig && !exact)
00470 {
00471 if (opterr)
00472 fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
00473 exec_name, argv[optind]);
00474 nextchar += strlen (nextchar);
00475 optind++;
00476 return '?';
00477 }
00478
00479 if (pfound != NULL)
00480 {
00481 option_index = indfound;
00482 optind++;
00483 if (*s)
00484 {
00485
00486
00487 if (pfound->has_arg)
00488 optarg = s + 1;
00489 else
00490 {
00491 if (opterr)
00492 {
00493 if (argv[optind - 1][1] == '-')
00494
00495 fprintf (stderr,
00496 _("%s: option `--%s' doesn't allow an argument\n"),
00497 exec_name, pfound->name);
00498 else
00499
00500 fprintf (stderr,
00501 _("%s: option `%c%s' doesn't allow an argument\n"),
00502 exec_name, argv[optind - 1][0], pfound->name);
00503 }
00504 nextchar += strlen (nextchar);
00505 return '?';
00506 }
00507 }
00508 else if (pfound->has_arg == 1)
00509 {
00510 if (optind < argc)
00511 optarg = argv[optind++];
00512 else
00513 {
00514 if (opterr)
00515 fprintf (stderr,
00516 _("%s: option `%s' requires an argument\n"),
00517 exec_name, argv[optind - 1]);
00518 nextchar += strlen (nextchar);
00519 return optstring[0] == ':' ? ':' : '?';
00520 }
00521 }
00522 nextchar += strlen (nextchar);
00523 if (longind != NULL)
00524 *longind = option_index;
00525 if (pfound->flag)
00526 {
00527 *(pfound->flag) = pfound->val;
00528 return 0;
00529 }
00530 return pfound->val;
00531 }
00532
00533
00534
00535
00536 if (!long_only || argv[optind][1] == '-'
00537 #ifdef GETOPT_COMPAT
00538 || argv[optind][0] == '+'
00539 #endif
00540 || my_index (optstring, *nextchar) == NULL)
00541 {
00542 if (opterr)
00543 {
00544 if (argv[optind][1] == '-')
00545
00546 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
00547 exec_name, nextchar);
00548 else
00549
00550 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
00551 exec_name, argv[optind][0], nextchar);
00552 }
00553 nextchar = (char *) "";
00554 optind++;
00555 return '?';
00556 }
00557 }
00558
00559
00560
00561 {
00562 char c = *nextchar++;
00563 char *temp = my_index (optstring, c);
00564
00565
00566 if (*nextchar == '\0')
00567 ++optind;
00568
00569 if (temp == NULL || c == ':')
00570 {
00571 if (opterr)
00572 {
00573 #if 0
00574 if (c < 040 || c >= 0177)
00575 fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
00576 exec_name, c);
00577 else
00578 fprintf (stderr, "%s: unrecognized option `-%c'\n", exec_name, c);
00579 #else
00580
00581 fprintf (stderr, _("%s: illegal option -- %c\n"), exec_name, c);
00582 #endif
00583 }
00584 optopt = c;
00585 return '?';
00586 }
00587 if (temp[1] == ':')
00588 {
00589 if (temp[2] == ':')
00590 {
00591
00592 if (*nextchar != '\0')
00593 {
00594 optarg = nextchar;
00595 optind++;
00596 }
00597 else
00598 optarg = 0;
00599 nextchar = NULL;
00600 }
00601 else
00602 {
00603
00604 if (*nextchar != '\0')
00605 {
00606 optarg = nextchar;
00607
00608
00609 optind++;
00610 }
00611 else if (optind == argc)
00612 {
00613 if (opterr)
00614 {
00615 #if 0
00616 fprintf (stderr, "%s: option `-%c' requires an argument\n",
00617 exec_name, c);
00618 #else
00619
00620 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
00621 exec_name, c);
00622 #endif
00623 }
00624 optopt = c;
00625 if (optstring[0] == ':')
00626 c = ':';
00627 else
00628 c = '?';
00629 }
00630 else
00631
00632
00633 optarg = argv[optind++];
00634 nextchar = NULL;
00635 }
00636 }
00637 return c;
00638 }
00639 }
00640
00641
00642 int
00643 getopt_long (int argc, char *const *argv, const char *shortopts,
00644 const struct option *longopts, int *longind)
00645 {
00646 return _getopt_internal (argc, argv, shortopts, longopts, longind, 0);
00647 }
00648
00649 int
00650 getopt (int argc, char *const *argv, const char *optstring)
00651 {
00652 return _getopt_internal (argc, argv, optstring,
00653 (const struct option *) 0,
00654 (int *) 0,
00655 0);
00656 }
00657
00658 #endif
00659
00660 #ifdef TEST
00661
00662
00663
00664
00665 int
00666 main (argc, argv)
00667 int argc;
00668 char **argv;
00669 {
00670 int c;
00671 int digit_optind = 0;
00672
00673 while (1)
00674 {
00675 int this_option_optind = optind ? optind : 1;
00676
00677 c = getopt (argc, argv, "abc:d:0123456789");
00678 if (c == EOF)
00679 break;
00680
00681 switch (c)
00682 {
00683 case '0':
00684 case '1':
00685 case '2':
00686 case '3':
00687 case '4':
00688 case '5':
00689 case '6':
00690 case '7':
00691 case '8':
00692 case '9':
00693 if (digit_optind != 0 && digit_optind != this_option_optind)
00694 printf ("digits occur in two different argv-elements.\n");
00695 digit_optind = this_option_optind;
00696 printf ("option %c\n", c);
00697 break;
00698
00699 case 'a':
00700 printf ("option a\n");
00701 break;
00702
00703 case 'b':
00704 printf ("option b\n");
00705 break;
00706
00707 case 'c':
00708 printf ("option c with value `%s'\n", optarg);
00709 break;
00710
00711 case '?':
00712 break;
00713
00714 default:
00715 printf ("?? getopt returned character code 0%o ??\n", c);
00716 }
00717 }
00718
00719 if (optind < argc)
00720 {
00721 printf ("non-option ARGV-elements: ");
00722 while (optind < argc)
00723 printf ("%s ", argv[optind++]);
00724 printf ("\n");
00725 }
00726
00727 exit (0);
00728 }
00729
00730 #endif