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