COOPY » Guide
version 0.6.5
|
00001 /* Getopt for GNU. 00002 NOTE: getopt is part of the C library, so if you don't know what 00003 "Keep this file name-space clean" means, talk to drepper@gnu.org 00004 before changing it! 00005 Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2012 Free Software 00006 Foundation, Inc. 00007 This file is part of the GNU C Library. 00008 00009 This program is free software: you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00021 00022 #include "gnulib_getopt/getopt.h" 00023 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 #include <string.h> 00027 #include <unistd.h> 00028 00029 #include "gnulib_getopt/gettext.h" 00030 //#ifdef _LIBC 00031 //# include <libintl.h> 00032 //#else 00033 //# include "gettext.h" 00034 //# define _(msgid) gettext (msgid) 00035 //#endif 00036 00037 //#if defined _LIBC && defined USE_IN_LIBIO 00038 //# include <wchar.h> 00039 //#endif 00040 00041 /* This version of 'getopt' appears to the caller like standard Unix 'getopt' 00042 but it behaves differently for the user, since it allows the user 00043 to intersperse the options with the other arguments. 00044 00045 As 'getopt_long' works, it permutes the elements of ARGV so that, 00046 when it is done, all the options precede everything else. Thus 00047 all application programs are extended to handle flexible argument order. 00048 00049 Using 'getopt' or setting the environment variable POSIXLY_CORRECT 00050 disables permutation. 00051 Then the behavior is completely standard. 00052 00053 GNU application programs can use a third alternative mode in which 00054 they can distinguish the relative order of options and other arguments. */ 00055 00056 #include "gnulib_getopt/getopt_int.h" 00057 00058 /* For communication from 'getopt' to the caller. 00059 When 'getopt' finds an option that takes an argument, 00060 the argument value is returned here. 00061 Also, when 'ordering' is RETURN_IN_ORDER, 00062 each non-option ARGV-element is returned here. */ 00063 00064 char *optarg; 00065 00066 /* Index in ARGV of the next element to be scanned. 00067 This is used for communication to and from the caller 00068 and for communication between successive calls to 'getopt'. 00069 00070 On entry to 'getopt', zero means this is the first call; initialize. 00071 00072 When 'getopt' returns -1, this is the index of the first of the 00073 non-option elements that the caller should itself scan. 00074 00075 Otherwise, 'optind' communicates from one call to the next 00076 how much of ARGV has been scanned so far. */ 00077 00078 /* 1003.2 says this must be 1 before any call. */ 00079 int optind = 1; 00080 00081 /* Callers store zero here to inhibit the error message 00082 for unrecognized options. */ 00083 00084 int opterr = 1; 00085 00086 /* Set to an option character which was unrecognized. 00087 This must be initialized on some systems to avoid linking in the 00088 system's own getopt implementation. */ 00089 00090 int optopt = '?'; 00091 00092 /* Keep a global copy of all internal members of getopt_data. */ 00093 00094 static struct _getopt_data getopt_data; 00095 00096 00097 #if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV 00098 extern char *getenv (); 00099 #endif 00100 00101 #ifdef _LIBC 00102 /* Stored original parameters. 00103 XXX This is no good solution. We should rather copy the args so 00104 that we can compare them later. But we must not use malloc(3). */ 00105 extern int __libc_argc; 00106 extern char **__libc_argv; 00107 00108 /* Bash 2.0 gives us an environment variable containing flags 00109 indicating ARGV elements that should not be considered arguments. */ 00110 00111 # ifdef USE_NONOPTION_FLAGS 00112 /* Defined in getopt_init.c */ 00113 extern char *__getopt_nonoption_flags; 00114 # endif 00115 00116 # ifdef USE_NONOPTION_FLAGS 00117 # define SWAP_FLAGS(ch1, ch2) \ 00118 if (d->__nonoption_flags_len > 0) \ 00119 { \ 00120 char __tmp = __getopt_nonoption_flags[ch1]; \ 00121 __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ 00122 __getopt_nonoption_flags[ch2] = __tmp; \ 00123 } 00124 # else 00125 # define SWAP_FLAGS(ch1, ch2) 00126 # endif 00127 #else /* !_LIBC */ 00128 # define SWAP_FLAGS(ch1, ch2) 00129 #endif /* _LIBC */ 00130 00131 #define _(x) x 00132 00133 /* Exchange two adjacent subsequences of ARGV. 00134 One subsequence is elements [first_nonopt,last_nonopt) 00135 which contains all the non-options that have been skipped so far. 00136 The other is elements [last_nonopt,optind), which contains all 00137 the options processed since those non-options were skipped. 00138 00139 'first_nonopt' and 'last_nonopt' are relocated so that they describe 00140 the new indices of the non-options in ARGV after they are moved. */ 00141 00142 static void 00143 exchange (char **argv, struct _getopt_data *d) 00144 { 00145 int bottom = d->__first_nonopt; 00146 int middle = d->__last_nonopt; 00147 int top = d->optind; 00148 char *tem; 00149 00150 /* Exchange the shorter segment with the far end of the longer segment. 00151 That puts the shorter segment into the right place. 00152 It leaves the longer segment in the right place overall, 00153 but it consists of two parts that need to be swapped next. */ 00154 00155 #if defined _LIBC && defined USE_NONOPTION_FLAGS 00156 /* First make sure the handling of the '__getopt_nonoption_flags' 00157 string can work normally. Our top argument must be in the range 00158 of the string. */ 00159 if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) 00160 { 00161 /* We must extend the array. The user plays games with us and 00162 presents new arguments. */ 00163 char *new_str = malloc (top + 1); 00164 if (new_str == NULL) 00165 d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; 00166 else 00167 { 00168 memset (__mempcpy (new_str, __getopt_nonoption_flags, 00169 d->__nonoption_flags_max_len), 00170 '\0', top + 1 - d->__nonoption_flags_max_len); 00171 d->__nonoption_flags_max_len = top + 1; 00172 __getopt_nonoption_flags = new_str; 00173 } 00174 } 00175 #endif 00176 00177 while (top > middle && middle > bottom) 00178 { 00179 if (top - middle > middle - bottom) 00180 { 00181 /* Bottom segment is the short one. */ 00182 int len = middle - bottom; 00183 register int i; 00184 00185 /* Swap it with the top part of the top segment. */ 00186 for (i = 0; i < len; i++) 00187 { 00188 tem = argv[bottom + i]; 00189 argv[bottom + i] = argv[top - (middle - bottom) + i]; 00190 argv[top - (middle - bottom) + i] = tem; 00191 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); 00192 } 00193 /* Exclude the moved bottom segment from further swapping. */ 00194 top -= len; 00195 } 00196 else 00197 { 00198 /* Top segment is the short one. */ 00199 int len = top - middle; 00200 register int i; 00201 00202 /* Swap it with the bottom part of the bottom segment. */ 00203 for (i = 0; i < len; i++) 00204 { 00205 tem = argv[bottom + i]; 00206 argv[bottom + i] = argv[middle + i]; 00207 argv[middle + i] = tem; 00208 SWAP_FLAGS (bottom + i, middle + i); 00209 } 00210 /* Exclude the moved top segment from further swapping. */ 00211 bottom += len; 00212 } 00213 } 00214 00215 /* Update records for the slots the non-options now occupy. */ 00216 00217 d->__first_nonopt += (d->optind - d->__last_nonopt); 00218 d->__last_nonopt = d->optind; 00219 } 00220 00221 /* Initialize the internal data when the first call is made. */ 00222 00223 static const char * 00224 _getopt_initialize (int argc, 00225 char **argv, const char *optstring, 00226 struct _getopt_data *d, int posixly_correct) 00227 { 00228 /* Start processing options with ARGV-element 1 (since ARGV-element 0 00229 is the program name); the sequence of previously skipped 00230 non-option ARGV-elements is empty. */ 00231 00232 d->__first_nonopt = d->__last_nonopt = d->optind; 00233 00234 d->__nextchar = NULL; 00235 00236 d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT"); 00237 00238 /* Determine how to handle the ordering of options and nonoptions. */ 00239 00240 if (optstring[0] == '-') 00241 { 00242 d->__ordering = RETURN_IN_ORDER; 00243 ++optstring; 00244 } 00245 else if (optstring[0] == '+') 00246 { 00247 d->__ordering = REQUIRE_ORDER; 00248 ++optstring; 00249 } 00250 else if (d->__posixly_correct) 00251 d->__ordering = REQUIRE_ORDER; 00252 else 00253 d->__ordering = PERMUTE; 00254 00255 #if defined _LIBC && defined USE_NONOPTION_FLAGS 00256 if (!d->__posixly_correct 00257 && argc == __libc_argc && argv == __libc_argv) 00258 { 00259 if (d->__nonoption_flags_max_len == 0) 00260 { 00261 if (__getopt_nonoption_flags == NULL 00262 || __getopt_nonoption_flags[0] == '\0') 00263 d->__nonoption_flags_max_len = -1; 00264 else 00265 { 00266 const char *orig_str = __getopt_nonoption_flags; 00267 int len = d->__nonoption_flags_max_len = strlen (orig_str); 00268 if (d->__nonoption_flags_max_len < argc) 00269 d->__nonoption_flags_max_len = argc; 00270 __getopt_nonoption_flags = 00271 (char *) malloc (d->__nonoption_flags_max_len); 00272 if (__getopt_nonoption_flags == NULL) 00273 d->__nonoption_flags_max_len = -1; 00274 else 00275 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), 00276 '\0', d->__nonoption_flags_max_len - len); 00277 } 00278 } 00279 d->__nonoption_flags_len = d->__nonoption_flags_max_len; 00280 } 00281 else 00282 d->__nonoption_flags_len = 0; 00283 #endif 00284 00285 return optstring; 00286 } 00287 00288 /* Scan elements of ARGV (whose length is ARGC) for option characters 00289 given in OPTSTRING. 00290 00291 If an element of ARGV starts with '-', and is not exactly "-" or "--", 00292 then it is an option element. The characters of this element 00293 (aside from the initial '-') are option characters. If 'getopt' 00294 is called repeatedly, it returns successively each of the option characters 00295 from each of the option elements. 00296 00297 If 'getopt' finds another option character, it returns that character, 00298 updating 'optind' and 'nextchar' so that the next call to 'getopt' can 00299 resume the scan with the following option character or ARGV-element. 00300 00301 If there are no more option characters, 'getopt' returns -1. 00302 Then 'optind' is the index in ARGV of the first ARGV-element 00303 that is not an option. (The ARGV-elements have been permuted 00304 so that those that are not options now come last.) 00305 00306 OPTSTRING is a string containing the legitimate option characters. 00307 If an option character is seen that is not listed in OPTSTRING, 00308 return '?' after printing an error message. If you set 'opterr' to 00309 zero, the error message is suppressed but we still return '?'. 00310 00311 If a char in OPTSTRING is followed by a colon, that means it wants an arg, 00312 so the following text in the same ARGV-element, or the text of the following 00313 ARGV-element, is returned in 'optarg'. Two colons mean an option that 00314 wants an optional arg; if there is text in the current ARGV-element, 00315 it is returned in 'optarg', otherwise 'optarg' is set to zero. 00316 00317 If OPTSTRING starts with '-' or '+', it requests different methods of 00318 handling the non-option ARGV-elements. 00319 See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. 00320 00321 Long-named options begin with '--' instead of '-'. 00322 Their names may be abbreviated as long as the abbreviation is unique 00323 or is an exact match for some defined option. If they have an 00324 argument, it follows the option name in the same ARGV-element, separated 00325 from the option name by a '=', or else the in next ARGV-element. 00326 When 'getopt' finds a long-named option, it returns 0 if that option's 00327 'flag' field is nonzero, the value of the option's 'val' field 00328 if the 'flag' field is zero. 00329 00330 The elements of ARGV aren't really const, because we permute them. 00331 But we pretend they're const in the prototype to be compatible 00332 with other systems. 00333 00334 LONGOPTS is a vector of 'struct option' terminated by an 00335 element containing a name which is zero. 00336 00337 LONGIND returns the index in LONGOPT of the long-named option found. 00338 It is only valid when a long-named option has been found by the most 00339 recent call. 00340 00341 If LONG_ONLY is nonzero, '-' as well as '--' can introduce 00342 long-named options. */ 00343 00344 int 00345 _getopt_internal_r (int argc, char **argv, const char *optstring, 00346 const struct option *longopts, int *longind, 00347 int long_only, struct _getopt_data *d, int posixly_correct) 00348 { 00349 int print_errors = d->opterr; 00350 00351 if (argc < 1) 00352 return -1; 00353 00354 d->optarg = NULL; 00355 00356 if (d->optind == 0 || !d->__initialized) 00357 { 00358 if (d->optind == 0) 00359 d->optind = 1; /* Don't scan ARGV[0], the program name. */ 00360 optstring = _getopt_initialize (argc, argv, optstring, d, 00361 posixly_correct); 00362 d->__initialized = 1; 00363 } 00364 else if (optstring[0] == '-' || optstring[0] == '+') 00365 optstring++; 00366 if (optstring[0] == ':') 00367 print_errors = 0; 00368 00369 /* Test whether ARGV[optind] points to a non-option argument. 00370 Either it does not have option syntax, or there is an environment flag 00371 from the shell indicating it is not an option. The later information 00372 is only used when the used in the GNU libc. */ 00373 #if defined _LIBC && defined USE_NONOPTION_FLAGS 00374 # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ 00375 || (d->optind < d->__nonoption_flags_len \ 00376 && __getopt_nonoption_flags[d->optind] == '1')) 00377 #else 00378 # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') 00379 #endif 00380 00381 if (d->__nextchar == NULL || *d->__nextchar == '\0') 00382 { 00383 /* Advance to the next ARGV-element. */ 00384 00385 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been 00386 moved back by the user (who may also have changed the arguments). */ 00387 if (d->__last_nonopt > d->optind) 00388 d->__last_nonopt = d->optind; 00389 if (d->__first_nonopt > d->optind) 00390 d->__first_nonopt = d->optind; 00391 00392 if (d->__ordering == PERMUTE) 00393 { 00394 /* If we have just processed some options following some non-options, 00395 exchange them so that the options come first. */ 00396 00397 if (d->__first_nonopt != d->__last_nonopt 00398 && d->__last_nonopt != d->optind) 00399 exchange ((char **) argv, d); 00400 else if (d->__last_nonopt != d->optind) 00401 d->__first_nonopt = d->optind; 00402 00403 /* Skip any additional non-options 00404 and extend the range of non-options previously skipped. */ 00405 00406 while (d->optind < argc && NONOPTION_P) 00407 d->optind++; 00408 d->__last_nonopt = d->optind; 00409 } 00410 00411 /* The special ARGV-element '--' means premature end of options. 00412 Skip it like a null option, 00413 then exchange with previous non-options as if it were an option, 00414 then skip everything else like a non-option. */ 00415 00416 if (d->optind != argc && !strcmp (argv[d->optind], "--")) 00417 { 00418 d->optind++; 00419 00420 if (d->__first_nonopt != d->__last_nonopt 00421 && d->__last_nonopt != d->optind) 00422 exchange ((char **) argv, d); 00423 else if (d->__first_nonopt == d->__last_nonopt) 00424 d->__first_nonopt = d->optind; 00425 d->__last_nonopt = argc; 00426 00427 d->optind = argc; 00428 } 00429 00430 /* If we have done all the ARGV-elements, stop the scan 00431 and back over any non-options that we skipped and permuted. */ 00432 00433 if (d->optind == argc) 00434 { 00435 /* Set the next-arg-index to point at the non-options 00436 that we previously skipped, so the caller will digest them. */ 00437 if (d->__first_nonopt != d->__last_nonopt) 00438 d->optind = d->__first_nonopt; 00439 return -1; 00440 } 00441 00442 /* If we have come to a non-option and did not permute it, 00443 either stop the scan or describe it to the caller and pass it by. */ 00444 00445 if (NONOPTION_P) 00446 { 00447 if (d->__ordering == REQUIRE_ORDER) 00448 return -1; 00449 d->optarg = argv[d->optind++]; 00450 return 1; 00451 } 00452 00453 /* We have found another option-ARGV-element. 00454 Skip the initial punctuation. */ 00455 00456 d->__nextchar = (argv[d->optind] + 1 00457 + (longopts != NULL && argv[d->optind][1] == '-')); 00458 } 00459 00460 /* Decode the current option-ARGV-element. */ 00461 00462 /* Check whether the ARGV-element is a long option. 00463 00464 If long_only and the ARGV-element has the form "-f", where f is 00465 a valid short option, don't consider it an abbreviated form of 00466 a long option that starts with f. Otherwise there would be no 00467 way to give the -f short option. 00468 00469 On the other hand, if there's a long option "fubar" and 00470 the ARGV-element is "-fu", do consider that an abbreviation of 00471 the long option, just like "--fu", and not "-f" with arg "u". 00472 00473 This distinction seems to be the most useful approach. */ 00474 00475 if (longopts != NULL 00476 && (argv[d->optind][1] == '-' 00477 || (long_only && (argv[d->optind][2] 00478 || !strchr (optstring, argv[d->optind][1]))))) 00479 { 00480 char *nameend; 00481 unsigned int namelen; 00482 const struct option *p; 00483 const struct option *pfound = NULL; 00484 struct option_list 00485 { 00486 const struct option *p; 00487 struct option_list *next; 00488 } *ambig_list = NULL; 00489 int exact = 0; 00490 int indfound = -1; 00491 int option_index; 00492 00493 for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) 00494 /* Do nothing. */ ; 00495 namelen = nameend - d->__nextchar; 00496 00497 /* Test all long options for either exact match 00498 or abbreviated matches. */ 00499 for (p = longopts, option_index = 0; p->name; p++, option_index++) 00500 if (!strncmp (p->name, d->__nextchar, namelen)) 00501 { 00502 if (namelen == (unsigned int) strlen (p->name)) 00503 { 00504 /* Exact match found. */ 00505 pfound = p; 00506 indfound = option_index; 00507 exact = 1; 00508 break; 00509 } 00510 else if (pfound == NULL) 00511 { 00512 /* First nonexact match found. */ 00513 pfound = p; 00514 indfound = option_index; 00515 } 00516 else if (long_only 00517 || pfound->has_arg != p->has_arg 00518 || pfound->flag != p->flag 00519 || pfound->val != p->val) 00520 { 00521 /* Second or later nonexact match found. */ 00522 struct option_list *newp = malloc (sizeof (*newp)); 00523 newp->p = p; 00524 newp->next = ambig_list; 00525 ambig_list = newp; 00526 } 00527 } 00528 00529 if (ambig_list != NULL && !exact) 00530 { 00531 if (print_errors) 00532 { 00533 struct option_list first; 00534 first.p = pfound; 00535 first.next = ambig_list; 00536 ambig_list = &first; 00537 00538 #if defined _LIBC && defined USE_IN_LIBIO 00539 char *buf = NULL; 00540 size_t buflen = 0; 00541 00542 FILE *fp = open_memstream (&buf, &buflen); 00543 if (fp != NULL) 00544 { 00545 fprintf (fp, 00546 _("%s: option '%s' is ambiguous; possibilities:"), 00547 argv[0], argv[d->optind]); 00548 00549 do 00550 { 00551 fprintf (fp, " '--%s'", ambig_list->p->name); 00552 ambig_list = ambig_list->next; 00553 } 00554 while (ambig_list != NULL); 00555 00556 fputc_unlocked ('\n', fp); 00557 00558 if (__builtin_expect (fclose (fp) != EOF, 1)) 00559 { 00560 _IO_flockfile (stderr); 00561 00562 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 00563 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; 00564 00565 __fxprintf (NULL, "%s", buf); 00566 00567 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 00568 _IO_funlockfile (stderr); 00569 00570 free (buf); 00571 } 00572 } 00573 #else 00574 fprintf (stderr, 00575 _("%s: option '%s' is ambiguous; possibilities:"), 00576 argv[0], argv[d->optind]); 00577 do 00578 { 00579 fprintf (stderr, " '--%s'", ambig_list->p->name); 00580 ambig_list = ambig_list->next; 00581 } 00582 while (ambig_list != NULL); 00583 00584 fputc ('\n', stderr); 00585 #endif 00586 } 00587 d->__nextchar += strlen (d->__nextchar); 00588 d->optind++; 00589 d->optopt = 0; 00590 return '?'; 00591 } 00592 00593 while (ambig_list != NULL) 00594 { 00595 struct option_list *pn = ambig_list->next; 00596 free (ambig_list); 00597 ambig_list = pn; 00598 } 00599 00600 if (pfound != NULL) 00601 { 00602 option_index = indfound; 00603 d->optind++; 00604 if (*nameend) 00605 { 00606 /* Don't test has_arg with >, because some C compilers don't 00607 allow it to be used on enums. */ 00608 if (pfound->has_arg) 00609 d->optarg = nameend + 1; 00610 else 00611 { 00612 if (print_errors) 00613 { 00614 #if defined _LIBC && defined USE_IN_LIBIO 00615 char *buf; 00616 int n; 00617 #endif 00618 00619 if (argv[d->optind - 1][1] == '-') 00620 { 00621 /* --option */ 00622 #if defined _LIBC && defined USE_IN_LIBIO 00623 n = __asprintf (&buf, _("\ 00624 %s: option '--%s' doesn't allow an argument\n"), 00625 argv[0], pfound->name); 00626 #else 00627 fprintf (stderr, _("\ 00628 %s: option '--%s' doesn't allow an argument\n"), 00629 argv[0], pfound->name); 00630 #endif 00631 } 00632 else 00633 { 00634 /* +option or -option */ 00635 #if defined _LIBC && defined USE_IN_LIBIO 00636 n = __asprintf (&buf, _("\ 00637 %s: option '%c%s' doesn't allow an argument\n"), 00638 argv[0], argv[d->optind - 1][0], 00639 pfound->name); 00640 #else 00641 fprintf (stderr, _("\ 00642 %s: option '%c%s' doesn't allow an argument\n"), 00643 argv[0], argv[d->optind - 1][0], 00644 pfound->name); 00645 #endif 00646 } 00647 00648 #if defined _LIBC && defined USE_IN_LIBIO 00649 if (n >= 0) 00650 { 00651 _IO_flockfile (stderr); 00652 00653 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 00654 ((_IO_FILE *) stderr)->_flags2 00655 |= _IO_FLAGS2_NOTCANCEL; 00656 00657 __fxprintf (NULL, "%s", buf); 00658 00659 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 00660 _IO_funlockfile (stderr); 00661 00662 free (buf); 00663 } 00664 #endif 00665 } 00666 00667 d->__nextchar += strlen (d->__nextchar); 00668 00669 d->optopt = pfound->val; 00670 return '?'; 00671 } 00672 } 00673 else if (pfound->has_arg == 1) 00674 { 00675 if (d->optind < argc) 00676 d->optarg = argv[d->optind++]; 00677 else 00678 { 00679 if (print_errors) 00680 { 00681 #if defined _LIBC && defined USE_IN_LIBIO 00682 char *buf; 00683 00684 if (__asprintf (&buf, _("\ 00685 %s: option '--%s' requires an argument\n"), 00686 argv[0], pfound->name) >= 0) 00687 { 00688 _IO_flockfile (stderr); 00689 00690 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 00691 ((_IO_FILE *) stderr)->_flags2 00692 |= _IO_FLAGS2_NOTCANCEL; 00693 00694 __fxprintf (NULL, "%s", buf); 00695 00696 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 00697 _IO_funlockfile (stderr); 00698 00699 free (buf); 00700 } 00701 #else 00702 fprintf (stderr, 00703 _("%s: option '--%s' requires an argument\n"), 00704 argv[0], pfound->name); 00705 #endif 00706 } 00707 d->__nextchar += strlen (d->__nextchar); 00708 d->optopt = pfound->val; 00709 return optstring[0] == ':' ? ':' : '?'; 00710 } 00711 } 00712 d->__nextchar += strlen (d->__nextchar); 00713 if (longind != NULL) 00714 *longind = option_index; 00715 if (pfound->flag) 00716 { 00717 *(pfound->flag) = pfound->val; 00718 return 0; 00719 } 00720 return pfound->val; 00721 } 00722 00723 /* Can't find it as a long option. If this is not getopt_long_only, 00724 or the option starts with '--' or is not a valid short 00725 option, then it's an error. 00726 Otherwise interpret it as a short option. */ 00727 if (!long_only || argv[d->optind][1] == '-' 00728 || strchr (optstring, *d->__nextchar) == NULL) 00729 { 00730 if (print_errors) 00731 { 00732 #if defined _LIBC && defined USE_IN_LIBIO 00733 char *buf; 00734 int n; 00735 #endif 00736 00737 if (argv[d->optind][1] == '-') 00738 { 00739 /* --option */ 00740 #if defined _LIBC && defined USE_IN_LIBIO 00741 n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"), 00742 argv[0], d->__nextchar); 00743 #else 00744 fprintf (stderr, _("%s: unrecognized option '--%s'\n"), 00745 argv[0], d->__nextchar); 00746 #endif 00747 } 00748 else 00749 { 00750 /* +option or -option */ 00751 #if defined _LIBC && defined USE_IN_LIBIO 00752 n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"), 00753 argv[0], argv[d->optind][0], d->__nextchar); 00754 #else 00755 fprintf (stderr, _("%s: unrecognized option '%c%s'\n"), 00756 argv[0], argv[d->optind][0], d->__nextchar); 00757 #endif 00758 } 00759 00760 #if defined _LIBC && defined USE_IN_LIBIO 00761 if (n >= 0) 00762 { 00763 _IO_flockfile (stderr); 00764 00765 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 00766 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; 00767 00768 __fxprintf (NULL, "%s", buf); 00769 00770 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 00771 _IO_funlockfile (stderr); 00772 00773 free (buf); 00774 } 00775 #endif 00776 } 00777 d->__nextchar = (char *) ""; 00778 d->optind++; 00779 d->optopt = 0; 00780 return '?'; 00781 } 00782 } 00783 00784 /* Look at and handle the next short option-character. */ 00785 00786 { 00787 char c = *d->__nextchar++; 00788 const char *temp = strchr (optstring, c); 00789 00790 /* Increment 'optind' when we start to process its last character. */ 00791 if (*d->__nextchar == '\0') 00792 ++d->optind; 00793 00794 if (temp == NULL || c == ':' || c == ';') 00795 { 00796 if (print_errors) 00797 { 00798 #if defined _LIBC && defined USE_IN_LIBIO 00799 char *buf; 00800 int n; 00801 #endif 00802 00803 #if defined _LIBC && defined USE_IN_LIBIO 00804 n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"), 00805 argv[0], c); 00806 #else 00807 fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); 00808 #endif 00809 00810 #if defined _LIBC && defined USE_IN_LIBIO 00811 if (n >= 0) 00812 { 00813 _IO_flockfile (stderr); 00814 00815 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 00816 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; 00817 00818 __fxprintf (NULL, "%s", buf); 00819 00820 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 00821 _IO_funlockfile (stderr); 00822 00823 free (buf); 00824 } 00825 #endif 00826 } 00827 d->optopt = c; 00828 return '?'; 00829 } 00830 /* Convenience. Treat POSIX -W foo same as long option --foo */ 00831 if (temp[0] == 'W' && temp[1] == ';') 00832 { 00833 char *nameend; 00834 const struct option *p; 00835 const struct option *pfound = NULL; 00836 int exact = 0; 00837 int ambig = 0; 00838 int indfound = 0; 00839 int option_index; 00840 00841 if (longopts == NULL) 00842 goto no_longs; 00843 00844 /* This is an option that requires an argument. */ 00845 if (*d->__nextchar != '\0') 00846 { 00847 d->optarg = d->__nextchar; 00848 /* If we end this ARGV-element by taking the rest as an arg, 00849 we must advance to the next element now. */ 00850 d->optind++; 00851 } 00852 else if (d->optind == argc) 00853 { 00854 if (print_errors) 00855 { 00856 #if defined _LIBC && defined USE_IN_LIBIO 00857 char *buf; 00858 00859 if (__asprintf (&buf, 00860 _("%s: option requires an argument -- '%c'\n"), 00861 argv[0], c) >= 0) 00862 { 00863 _IO_flockfile (stderr); 00864 00865 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 00866 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; 00867 00868 __fxprintf (NULL, "%s", buf); 00869 00870 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 00871 _IO_funlockfile (stderr); 00872 00873 free (buf); 00874 } 00875 #else 00876 fprintf (stderr, 00877 _("%s: option requires an argument -- '%c'\n"), 00878 argv[0], c); 00879 #endif 00880 } 00881 d->optopt = c; 00882 if (optstring[0] == ':') 00883 c = ':'; 00884 else 00885 c = '?'; 00886 return c; 00887 } 00888 else 00889 /* We already incremented 'd->optind' once; 00890 increment it again when taking next ARGV-elt as argument. */ 00891 d->optarg = argv[d->optind++]; 00892 00893 /* optarg is now the argument, see if it's in the 00894 table of longopts. */ 00895 00896 for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; 00897 nameend++) 00898 /* Do nothing. */ ; 00899 00900 /* Test all long options for either exact match 00901 or abbreviated matches. */ 00902 for (p = longopts, option_index = 0; p->name; p++, option_index++) 00903 if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) 00904 { 00905 if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name)) 00906 { 00907 /* Exact match found. */ 00908 pfound = p; 00909 indfound = option_index; 00910 exact = 1; 00911 break; 00912 } 00913 else if (pfound == NULL) 00914 { 00915 /* First nonexact match found. */ 00916 pfound = p; 00917 indfound = option_index; 00918 } 00919 else if (long_only 00920 || pfound->has_arg != p->has_arg 00921 || pfound->flag != p->flag 00922 || pfound->val != p->val) 00923 /* Second or later nonexact match found. */ 00924 ambig = 1; 00925 } 00926 if (ambig && !exact) 00927 { 00928 if (print_errors) 00929 { 00930 #if defined _LIBC && defined USE_IN_LIBIO 00931 char *buf; 00932 00933 if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"), 00934 argv[0], d->optarg) >= 0) 00935 { 00936 _IO_flockfile (stderr); 00937 00938 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 00939 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; 00940 00941 __fxprintf (NULL, "%s", buf); 00942 00943 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 00944 _IO_funlockfile (stderr); 00945 00946 free (buf); 00947 } 00948 #else 00949 fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"), 00950 argv[0], d->optarg); 00951 #endif 00952 } 00953 d->__nextchar += strlen (d->__nextchar); 00954 d->optind++; 00955 return '?'; 00956 } 00957 if (pfound != NULL) 00958 { 00959 option_index = indfound; 00960 if (*nameend) 00961 { 00962 /* Don't test has_arg with >, because some C compilers don't 00963 allow it to be used on enums. */ 00964 if (pfound->has_arg) 00965 d->optarg = nameend + 1; 00966 else 00967 { 00968 if (print_errors) 00969 { 00970 #if defined _LIBC && defined USE_IN_LIBIO 00971 char *buf; 00972 00973 if (__asprintf (&buf, _("\ 00974 %s: option '-W %s' doesn't allow an argument\n"), 00975 argv[0], pfound->name) >= 0) 00976 { 00977 _IO_flockfile (stderr); 00978 00979 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 00980 ((_IO_FILE *) stderr)->_flags2 00981 |= _IO_FLAGS2_NOTCANCEL; 00982 00983 __fxprintf (NULL, "%s", buf); 00984 00985 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 00986 _IO_funlockfile (stderr); 00987 00988 free (buf); 00989 } 00990 #else 00991 fprintf (stderr, _("\ 00992 %s: option '-W %s' doesn't allow an argument\n"), 00993 argv[0], pfound->name); 00994 #endif 00995 } 00996 00997 d->__nextchar += strlen (d->__nextchar); 00998 return '?'; 00999 } 01000 } 01001 else if (pfound->has_arg == 1) 01002 { 01003 if (d->optind < argc) 01004 d->optarg = argv[d->optind++]; 01005 else 01006 { 01007 if (print_errors) 01008 { 01009 #if defined _LIBC && defined USE_IN_LIBIO 01010 char *buf; 01011 01012 if (__asprintf (&buf, _("\ 01013 %s: option '-W %s' requires an argument\n"), 01014 argv[0], pfound->name) >= 0) 01015 { 01016 _IO_flockfile (stderr); 01017 01018 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 01019 ((_IO_FILE *) stderr)->_flags2 01020 |= _IO_FLAGS2_NOTCANCEL; 01021 01022 __fxprintf (NULL, "%s", buf); 01023 01024 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 01025 _IO_funlockfile (stderr); 01026 01027 free (buf); 01028 } 01029 #else 01030 fprintf (stderr, _("\ 01031 %s: option '-W %s' requires an argument\n"), 01032 argv[0], pfound->name); 01033 #endif 01034 } 01035 d->__nextchar += strlen (d->__nextchar); 01036 return optstring[0] == ':' ? ':' : '?'; 01037 } 01038 } 01039 else 01040 d->optarg = NULL; 01041 d->__nextchar += strlen (d->__nextchar); 01042 if (longind != NULL) 01043 *longind = option_index; 01044 if (pfound->flag) 01045 { 01046 *(pfound->flag) = pfound->val; 01047 return 0; 01048 } 01049 return pfound->val; 01050 } 01051 01052 no_longs: 01053 d->__nextchar = NULL; 01054 return 'W'; /* Let the application handle it. */ 01055 } 01056 if (temp[1] == ':') 01057 { 01058 if (temp[2] == ':') 01059 { 01060 /* This is an option that accepts an argument optionally. */ 01061 if (*d->__nextchar != '\0') 01062 { 01063 d->optarg = d->__nextchar; 01064 d->optind++; 01065 } 01066 else 01067 d->optarg = NULL; 01068 d->__nextchar = NULL; 01069 } 01070 else 01071 { 01072 /* This is an option that requires an argument. */ 01073 if (*d->__nextchar != '\0') 01074 { 01075 d->optarg = d->__nextchar; 01076 /* If we end this ARGV-element by taking the rest as an arg, 01077 we must advance to the next element now. */ 01078 d->optind++; 01079 } 01080 else if (d->optind == argc) 01081 { 01082 if (print_errors) 01083 { 01084 #if defined _LIBC && defined USE_IN_LIBIO 01085 char *buf; 01086 01087 if (__asprintf (&buf, _("\ 01088 %s: option requires an argument -- '%c'\n"), 01089 argv[0], c) >= 0) 01090 { 01091 _IO_flockfile (stderr); 01092 01093 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 01094 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; 01095 01096 __fxprintf (NULL, "%s", buf); 01097 01098 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 01099 _IO_funlockfile (stderr); 01100 01101 free (buf); 01102 } 01103 #else 01104 fprintf (stderr, 01105 _("%s: option requires an argument -- '%c'\n"), 01106 argv[0], c); 01107 #endif 01108 } 01109 d->optopt = c; 01110 if (optstring[0] == ':') 01111 c = ':'; 01112 else 01113 c = '?'; 01114 } 01115 else 01116 /* We already incremented 'optind' once; 01117 increment it again when taking next ARGV-elt as argument. */ 01118 d->optarg = argv[d->optind++]; 01119 d->__nextchar = NULL; 01120 } 01121 } 01122 return c; 01123 } 01124 } 01125 01126 int 01127 gnulib_getopt_internal (int argc, char **argv, const char *optstring, 01128 const struct option *longopts, int *longind, int long_only, 01129 int posixly_correct) 01130 { 01131 int result; 01132 01133 getopt_data.optind = optind; 01134 getopt_data.opterr = opterr; 01135 01136 result = _getopt_internal_r (argc, argv, optstring, longopts, 01137 longind, long_only, &getopt_data, 01138 posixly_correct); 01139 01140 optind = getopt_data.optind; 01141 optarg = getopt_data.optarg; 01142 optopt = getopt_data.optopt; 01143 01144 return result; 01145 } 01146 01147 /* glibc gets a LSB-compliant getopt. 01148 Standalone applications get a POSIX-compliant getopt. */ 01149 #if _LIBC 01150 enum { POSIXLY_CORRECT = 0 }; 01151 #else 01152 enum { POSIXLY_CORRECT = 1 }; 01153 #endif 01154 01155 int 01156 getopt (int argc, char *const *argv, const char *optstring) 01157 { 01158 return gnulib_getopt_internal (argc, (char **) argv, optstring, 01159 (const struct option *) 0, 01160 (int *) 0, 01161 0, POSIXLY_CORRECT); 01162 } 01163 01164 #ifdef _LIBC 01165 int 01166 __posix_getopt (int argc, char *const *argv, const char *optstring) 01167 { 01168 return gnulib_getopt_internal (argc, argv, optstring, 01169 (const struct option *) 0, 01170 (int *) 0, 01171 0, 1); 01172 } 01173 #endif 01174 01175 01176 #ifdef TEST 01177 01178 /* Compile with -DTEST to make an executable for use in testing 01179 the above definition of 'getopt'. */ 01180 01181 int 01182 main (int argc, char **argv) 01183 { 01184 int c; 01185 int digit_optind = 0; 01186 01187 while (1) 01188 { 01189 int this_option_optind = optind ? optind : 1; 01190 01191 c = getopt (argc, argv, "abc:d:0123456789"); 01192 if (c == -1) 01193 break; 01194 01195 switch (c) 01196 { 01197 case '0': 01198 case '1': 01199 case '2': 01200 case '3': 01201 case '4': 01202 case '5': 01203 case '6': 01204 case '7': 01205 case '8': 01206 case '9': 01207 if (digit_optind != 0 && digit_optind != this_option_optind) 01208 printf ("digits occur in two different argv-elements.\n"); 01209 digit_optind = this_option_optind; 01210 printf ("option %c\n", c); 01211 break; 01212 01213 case 'a': 01214 printf ("option a\n"); 01215 break; 01216 01217 case 'b': 01218 printf ("option b\n"); 01219 break; 01220 01221 case 'c': 01222 printf ("option c with value '%s'\n", optarg); 01223 break; 01224 01225 case '?': 01226 break; 01227 01228 default: 01229 printf ("?? getopt returned character code 0%o ??\n", c); 01230 } 01231 } 01232 01233 if (optind < argc) 01234 { 01235 printf ("non-option ARGV-elements: "); 01236 while (optind < argc) 01237 printf ("%s ", argv[optind++]); 01238 printf ("\n"); 01239 } 01240 01241 exit (0); 01242 } 01243 01244 #endif /* TEST */