Mercurial > vba-linux
diff src/sdl/getopt.c @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/sdl/getopt.c Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,1060 @@ 1.4 +/* Getopt for GNU. 1.5 + NOTE: getopt is now part of the C library, so if you don't know what 1.6 + "Keep this file name-space clean" means, talk to drepper@gnu.org 1.7 + before changing it! 1.8 + 1.9 + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 1.10 + Free Software Foundation, Inc. 1.11 + 1.12 + NOTE: This source is derived from an old version taken from the GNU C 1.13 + Library (glibc). 1.14 + 1.15 + This program is free software; you can redistribute it and/or modify it 1.16 + under the terms of the GNU General Public License as published by the 1.17 + Free Software Foundation; either version 2, or (at your option) any 1.18 + later version. 1.19 + 1.20 + This program is distributed in the hope that it will be useful, 1.21 + but WITHOUT ANY WARRANTY; without even the implied warranty of 1.22 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.23 + GNU General Public License for more details. 1.24 + 1.25 + You should have received a copy of the GNU General Public License 1.26 + along with this program; if not, write to the Free Software 1.27 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 1.28 + USA. */ 1.29 + 1.30 +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. 1.31 + Ditto for AIX 3.2 and <stdlib.h>. */ 1.32 +#ifndef _NO_PROTO 1.33 +# define _NO_PROTO 1.34 +#endif 1.35 + 1.36 +#ifdef HAVE_CONFIG_H 1.37 +# include <config.h> 1.38 +#endif 1.39 + 1.40 +#if !defined __STDC__ || !__STDC__ 1.41 +/* This is a separate conditional since some stdc systems 1.42 + reject `defined (const)'. */ 1.43 +# ifndef const 1.44 +# define const 1.45 +# endif 1.46 +#endif 1.47 + 1.48 +#include <stdio.h> 1.49 + 1.50 +/* Comment out all this code if we are using the GNU C Library, and are not 1.51 + actually compiling the library itself. This code is part of the GNU C 1.52 + Library, but also included in many other GNU distributions. Compiling 1.53 + and linking in this code is a waste when using the GNU C library 1.54 + (especially if it is a shared library). Rather than having every GNU 1.55 + program understand `configure --with-gnu-libc' and omit the object files, 1.56 + it is simpler to just do this in the source for each such file. */ 1.57 + 1.58 +#define GETOPT_INTERFACE_VERSION 2 1.59 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 1.60 +# include <gnu-versions.h> 1.61 +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION 1.62 +# define ELIDE_CODE 1.63 +# endif 1.64 +#endif 1.65 + 1.66 +#ifndef ELIDE_CODE 1.67 + 1.68 + 1.69 +/* This needs to come after some library #include 1.70 + to get __GNU_LIBRARY__ defined. */ 1.71 +#ifdef __GNU_LIBRARY__ 1.72 +/* Don't include stdlib.h for non-GNU C libraries because some of them 1.73 + contain conflicting prototypes for getopt. */ 1.74 +# include <stdlib.h> 1.75 +# include <unistd.h> 1.76 +#endif /* GNU C library. */ 1.77 + 1.78 +#ifdef VMS 1.79 +# include <unixlib.h> 1.80 +# if HAVE_STRING_H - 0 1.81 +# include <string.h> 1.82 +# endif 1.83 +#endif 1.84 + 1.85 +#ifndef _ 1.86 +/* This is for other GNU distributions with internationalized messages. 1.87 + When compiling libc, the _ macro is predefined. */ 1.88 +# ifdef HAVE_LIBINTL_H 1.89 +# include <libintl.h> 1.90 +# define _(msgid) gettext (msgid) 1.91 +# else 1.92 +# define _(msgid) (msgid) 1.93 +# endif 1.94 +#endif 1.95 + 1.96 +#ifdef _MSC_VER 1.97 +#include <string.h> 1.98 +#endif 1.99 + 1.100 +/* This version of `getopt' appears to the caller like standard Unix `getopt' 1.101 + but it behaves differently for the user, since it allows the user 1.102 + to intersperse the options with the other arguments. 1.103 + 1.104 + As `getopt' works, it permutes the elements of ARGV so that, 1.105 + when it is done, all the options precede everything else. Thus 1.106 + all application programs are extended to handle flexible argument order. 1.107 + 1.108 + Setting the environment variable POSIXLY_CORRECT disables permutation. 1.109 + Then the behavior is completely standard. 1.110 + 1.111 + GNU application programs can use a third alternative mode in which 1.112 + they can distinguish the relative order of options and other arguments. */ 1.113 + 1.114 +#include "getopt.h" 1.115 + 1.116 +/* For communication from `getopt' to the caller. 1.117 + When `getopt' finds an option that takes an argument, 1.118 + the argument value is returned here. 1.119 + Also, when `ordering' is RETURN_IN_ORDER, 1.120 + each non-option ARGV-element is returned here. */ 1.121 + 1.122 +char *optarg = NULL; 1.123 + 1.124 +/* Index in ARGV of the next element to be scanned. 1.125 + This is used for communication to and from the caller 1.126 + and for communication between successive calls to `getopt'. 1.127 + 1.128 + On entry to `getopt', zero means this is the first call; initialize. 1.129 + 1.130 + When `getopt' returns -1, this is the index of the first of the 1.131 + non-option elements that the caller should itself scan. 1.132 + 1.133 + Otherwise, `optind' communicates from one call to the next 1.134 + how much of ARGV has been scanned so far. */ 1.135 + 1.136 +/* 1003.2 says this must be 1 before any call. */ 1.137 +int optind = 1; 1.138 + 1.139 +/* Formerly, initialization of getopt depended on optind==0, which 1.140 + causes problems with re-calling getopt as programs generally don't 1.141 + know that. */ 1.142 + 1.143 +int __getopt_initialized = 0; 1.144 + 1.145 +/* The next char to be scanned in the option-element 1.146 + in which the last option character we returned was found. 1.147 + This allows us to pick up the scan where we left off. 1.148 + 1.149 + If this is zero, or a null string, it means resume the scan 1.150 + by advancing to the next ARGV-element. */ 1.151 + 1.152 +static char *nextchar; 1.153 + 1.154 +/* Callers store zero here to inhibit the error message 1.155 + for unrecognized options. */ 1.156 + 1.157 +int opterr = 1; 1.158 + 1.159 +/* Set to an option character which was unrecognized. 1.160 + This must be initialized on some systems to avoid linking in the 1.161 + system's own getopt implementation. */ 1.162 + 1.163 +int optopt = '?'; 1.164 + 1.165 +/* Describe how to deal with options that follow non-option ARGV-elements. 1.166 + 1.167 + If the caller did not specify anything, 1.168 + the default is REQUIRE_ORDER if the environment variable 1.169 + POSIXLY_CORRECT is defined, PERMUTE otherwise. 1.170 + 1.171 + REQUIRE_ORDER means don't recognize them as options; 1.172 + stop option processing when the first non-option is seen. 1.173 + This is what Unix does. 1.174 + This mode of operation is selected by either setting the environment 1.175 + variable POSIXLY_CORRECT, or using `+' as the first character 1.176 + of the list of option characters. 1.177 + 1.178 + PERMUTE is the default. We permute the contents of ARGV as we scan, 1.179 + so that eventually all the non-options are at the end. This allows options 1.180 + to be given in any order, even with programs that were not written to 1.181 + expect this. 1.182 + 1.183 + RETURN_IN_ORDER is an option available to programs that were written 1.184 + to expect options and other ARGV-elements in any order and that care about 1.185 + the ordering of the two. We describe each non-option ARGV-element 1.186 + as if it were the argument of an option with character code 1. 1.187 + Using `-' as the first character of the list of option characters 1.188 + selects this mode of operation. 1.189 + 1.190 + The special argument `--' forces an end of option-scanning regardless 1.191 + of the value of `ordering'. In the case of RETURN_IN_ORDER, only 1.192 + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ 1.193 + 1.194 +static enum 1.195 +{ 1.196 + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER 1.197 +} ordering; 1.198 + 1.199 +/* Value of POSIXLY_CORRECT environment variable. */ 1.200 +static char *posixly_correct; 1.201 + 1.202 +#ifdef __GNU_LIBRARY__ 1.203 +/* We want to avoid inclusion of string.h with non-GNU libraries 1.204 + because there are many ways it can cause trouble. 1.205 + On some systems, it contains special magic macros that don't work 1.206 + in GCC. */ 1.207 +# include <string.h> 1.208 +# define my_index strchr 1.209 +#else 1.210 + 1.211 +# if HAVE_STRING_H 1.212 +# include <string.h> 1.213 +# else 1.214 +# if HAVE_STRINGS_H 1.215 +# include <strings.h> 1.216 +# endif 1.217 +# endif 1.218 + 1.219 +/* Avoid depending on library functions or files 1.220 + whose names are inconsistent. */ 1.221 + 1.222 +#ifndef getenv 1.223 +extern char *getenv (); 1.224 +#endif 1.225 + 1.226 +static char * 1.227 +my_index (str, chr) 1.228 + const char *str; 1.229 + int chr; 1.230 +{ 1.231 + while (*str) 1.232 + { 1.233 + if (*str == chr) 1.234 + return (char *) str; 1.235 + str++; 1.236 + } 1.237 + return 0; 1.238 +} 1.239 + 1.240 +/* If using GCC, we can safely declare strlen this way. 1.241 + If not using GCC, it is ok not to declare it. */ 1.242 +#ifdef __GNUC__ 1.243 +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. 1.244 + That was relevant to code that was here before. */ 1.245 +# if (!defined __STDC__ || !__STDC__) && !defined strlen 1.246 +/* gcc with -traditional declares the built-in strlen to return int, 1.247 + and has done so at least since version 2.4.5. -- rms. */ 1.248 +extern int strlen (const char *); 1.249 +# endif /* not __STDC__ */ 1.250 +#endif /* __GNUC__ */ 1.251 + 1.252 +#endif /* not __GNU_LIBRARY__ */ 1.253 + 1.254 +/* Handle permutation of arguments. */ 1.255 + 1.256 +/* Describe the part of ARGV that contains non-options that have 1.257 + been skipped. `first_nonopt' is the index in ARGV of the first of them; 1.258 + `last_nonopt' is the index after the last of them. */ 1.259 + 1.260 +static int first_nonopt; 1.261 +static int last_nonopt; 1.262 + 1.263 +#ifdef _LIBC 1.264 +/* Bash 2.0 gives us an environment variable containing flags 1.265 + indicating ARGV elements that should not be considered arguments. */ 1.266 + 1.267 +/* Defined in getopt_init.c */ 1.268 +extern char *__getopt_nonoption_flags; 1.269 + 1.270 +static int nonoption_flags_max_len; 1.271 +static int nonoption_flags_len; 1.272 + 1.273 +static int original_argc; 1.274 +static char *const *original_argv; 1.275 + 1.276 +/* Make sure the environment variable bash 2.0 puts in the environment 1.277 + is valid for the getopt call we must make sure that the ARGV passed 1.278 + to getopt is that one passed to the process. */ 1.279 +static void 1.280 +__attribute__ ((unused)) 1.281 +store_args_and_env (int argc, char *const *argv) 1.282 +{ 1.283 + /* XXX This is no good solution. We should rather copy the args so 1.284 + that we can compare them later. But we must not use malloc(3). */ 1.285 + original_argc = argc; 1.286 + original_argv = argv; 1.287 +} 1.288 +# ifdef text_set_element 1.289 +text_set_element (__libc_subinit, store_args_and_env); 1.290 +# endif /* text_set_element */ 1.291 + 1.292 +# define SWAP_FLAGS(ch1, ch2) \ 1.293 + if (nonoption_flags_len > 0) \ 1.294 + { \ 1.295 + char __tmp = __getopt_nonoption_flags[ch1]; \ 1.296 + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ 1.297 + __getopt_nonoption_flags[ch2] = __tmp; \ 1.298 + } 1.299 +#else /* !_LIBC */ 1.300 +# define SWAP_FLAGS(ch1, ch2) 1.301 +#endif /* _LIBC */ 1.302 + 1.303 +/* Exchange two adjacent subsequences of ARGV. 1.304 + One subsequence is elements [first_nonopt,last_nonopt) 1.305 + which contains all the non-options that have been skipped so far. 1.306 + The other is elements [last_nonopt,optind), which contains all 1.307 + the options processed since those non-options were skipped. 1.308 + 1.309 + `first_nonopt' and `last_nonopt' are relocated so that they describe 1.310 + the new indices of the non-options in ARGV after they are moved. */ 1.311 + 1.312 +#if defined __STDC__ && __STDC__ 1.313 +static void exchange (char **); 1.314 +#endif 1.315 + 1.316 +static void 1.317 +exchange (argv) 1.318 + char **argv; 1.319 +{ 1.320 + int bottom = first_nonopt; 1.321 + int middle = last_nonopt; 1.322 + int top = optind; 1.323 + char *tem; 1.324 + 1.325 + /* Exchange the shorter segment with the far end of the longer segment. 1.326 + That puts the shorter segment into the right place. 1.327 + It leaves the longer segment in the right place overall, 1.328 + but it consists of two parts that need to be swapped next. */ 1.329 + 1.330 +#ifdef _LIBC 1.331 + /* First make sure the handling of the `__getopt_nonoption_flags' 1.332 + string can work normally. Our top argument must be in the range 1.333 + of the string. */ 1.334 + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) 1.335 + { 1.336 + /* We must extend the array. The user plays games with us and 1.337 + presents new arguments. */ 1.338 + char *new_str = malloc (top + 1); 1.339 + if (new_str == NULL) 1.340 + nonoption_flags_len = nonoption_flags_max_len = 0; 1.341 + else 1.342 + { 1.343 + memset (__mempcpy (new_str, __getopt_nonoption_flags, 1.344 + nonoption_flags_max_len), 1.345 + '\0', top + 1 - nonoption_flags_max_len); 1.346 + nonoption_flags_max_len = top + 1; 1.347 + __getopt_nonoption_flags = new_str; 1.348 + } 1.349 + } 1.350 +#endif 1.351 + 1.352 + while (top > middle && middle > bottom) 1.353 + { 1.354 + if (top - middle > middle - bottom) 1.355 + { 1.356 + /* Bottom segment is the short one. */ 1.357 + int len = middle - bottom; 1.358 + register int i; 1.359 + 1.360 + /* Swap it with the top part of the top segment. */ 1.361 + for (i = 0; i < len; i++) 1.362 + { 1.363 + tem = argv[bottom + i]; 1.364 + argv[bottom + i] = argv[top - (middle - bottom) + i]; 1.365 + argv[top - (middle - bottom) + i] = tem; 1.366 + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); 1.367 + } 1.368 + /* Exclude the moved bottom segment from further swapping. */ 1.369 + top -= len; 1.370 + } 1.371 + else 1.372 + { 1.373 + /* Top segment is the short one. */ 1.374 + int len = top - middle; 1.375 + register int i; 1.376 + 1.377 + /* Swap it with the bottom part of the bottom segment. */ 1.378 + for (i = 0; i < len; i++) 1.379 + { 1.380 + tem = argv[bottom + i]; 1.381 + argv[bottom + i] = argv[middle + i]; 1.382 + argv[middle + i] = tem; 1.383 + SWAP_FLAGS (bottom + i, middle + i); 1.384 + } 1.385 + /* Exclude the moved top segment from further swapping. */ 1.386 + bottom += len; 1.387 + } 1.388 + } 1.389 + 1.390 + /* Update records for the slots the non-options now occupy. */ 1.391 + 1.392 + first_nonopt += (optind - last_nonopt); 1.393 + last_nonopt = optind; 1.394 +} 1.395 + 1.396 +/* Initialize the internal data when the first call is made. */ 1.397 + 1.398 +#if defined __STDC__ && __STDC__ 1.399 +static const char *_getopt_initialize (int, char *const *, const char *); 1.400 +#endif 1.401 +static const char * 1.402 +_getopt_initialize (argc, argv, optstring) 1.403 + int argc; 1.404 + char *const *argv; 1.405 + const char *optstring; 1.406 +{ 1.407 + /* Start processing options with ARGV-element 1 (since ARGV-element 0 1.408 + is the program name); the sequence of previously skipped 1.409 + non-option ARGV-elements is empty. */ 1.410 + 1.411 + first_nonopt = last_nonopt = optind; 1.412 + 1.413 + nextchar = NULL; 1.414 + 1.415 + posixly_correct = getenv ("POSIXLY_CORRECT"); 1.416 + 1.417 + /* Determine how to handle the ordering of options and nonoptions. */ 1.418 + 1.419 + if (optstring[0] == '-') 1.420 + { 1.421 + ordering = RETURN_IN_ORDER; 1.422 + ++optstring; 1.423 + } 1.424 + else if (optstring[0] == '+') 1.425 + { 1.426 + ordering = REQUIRE_ORDER; 1.427 + ++optstring; 1.428 + } 1.429 + else if (posixly_correct != NULL) 1.430 + ordering = REQUIRE_ORDER; 1.431 + else 1.432 + ordering = PERMUTE; 1.433 + 1.434 +#ifdef _LIBC 1.435 + if (posixly_correct == NULL 1.436 + && argc == original_argc && argv == original_argv) 1.437 + { 1.438 + if (nonoption_flags_max_len == 0) 1.439 + { 1.440 + if (__getopt_nonoption_flags == NULL 1.441 + || __getopt_nonoption_flags[0] == '\0') 1.442 + nonoption_flags_max_len = -1; 1.443 + else 1.444 + { 1.445 + const char *orig_str = __getopt_nonoption_flags; 1.446 + int len = nonoption_flags_max_len = strlen (orig_str); 1.447 + if (nonoption_flags_max_len < argc) 1.448 + nonoption_flags_max_len = argc; 1.449 + __getopt_nonoption_flags = 1.450 + (char *) malloc (nonoption_flags_max_len); 1.451 + if (__getopt_nonoption_flags == NULL) 1.452 + nonoption_flags_max_len = -1; 1.453 + else 1.454 + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), 1.455 + '\0', nonoption_flags_max_len - len); 1.456 + } 1.457 + } 1.458 + nonoption_flags_len = nonoption_flags_max_len; 1.459 + } 1.460 + else 1.461 + nonoption_flags_len = 0; 1.462 +#endif 1.463 + 1.464 + return optstring; 1.465 +} 1.466 + 1.467 +/* Scan elements of ARGV (whose length is ARGC) for option characters 1.468 + given in OPTSTRING. 1.469 + 1.470 + If an element of ARGV starts with '-', and is not exactly "-" or "--", 1.471 + then it is an option element. The characters of this element 1.472 + (aside from the initial '-') are option characters. If `getopt' 1.473 + is called repeatedly, it returns successively each of the option characters 1.474 + from each of the option elements. 1.475 + 1.476 + If `getopt' finds another option character, it returns that character, 1.477 + updating `optind' and `nextchar' so that the next call to `getopt' can 1.478 + resume the scan with the following option character or ARGV-element. 1.479 + 1.480 + If there are no more option characters, `getopt' returns -1. 1.481 + Then `optind' is the index in ARGV of the first ARGV-element 1.482 + that is not an option. (The ARGV-elements have been permuted 1.483 + so that those that are not options now come last.) 1.484 + 1.485 + OPTSTRING is a string containing the legitimate option characters. 1.486 + If an option character is seen that is not listed in OPTSTRING, 1.487 + return '?' after printing an error message. If you set `opterr' to 1.488 + zero, the error message is suppressed but we still return '?'. 1.489 + 1.490 + If a char in OPTSTRING is followed by a colon, that means it wants an arg, 1.491 + so the following text in the same ARGV-element, or the text of the following 1.492 + ARGV-element, is returned in `optarg'. Two colons mean an option that 1.493 + wants an optional arg; if there is text in the current ARGV-element, 1.494 + it is returned in `optarg', otherwise `optarg' is set to zero. 1.495 + 1.496 + If OPTSTRING starts with `-' or `+', it requests different methods of 1.497 + handling the non-option ARGV-elements. 1.498 + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. 1.499 + 1.500 + Long-named options begin with `--' instead of `-'. 1.501 + Their names may be abbreviated as long as the abbreviation is unique 1.502 + or is an exact match for some defined option. If they have an 1.503 + argument, it follows the option name in the same ARGV-element, separated 1.504 + from the option name by a `=', or else the in next ARGV-element. 1.505 + When `getopt' finds a long-named option, it returns 0 if that option's 1.506 + `flag' field is nonzero, the value of the option's `val' field 1.507 + if the `flag' field is zero. 1.508 + 1.509 + The elements of ARGV aren't really const, because we permute them. 1.510 + But we pretend they're const in the prototype to be compatible 1.511 + with other systems. 1.512 + 1.513 + LONGOPTS is a vector of `struct option' terminated by an 1.514 + element containing a name which is zero. 1.515 + 1.516 + LONGIND returns the index in LONGOPT of the long-named option found. 1.517 + It is only valid when a long-named option has been found by the most 1.518 + recent call. 1.519 + 1.520 + If LONG_ONLY is nonzero, '-' as well as '--' can introduce 1.521 + long-named options. */ 1.522 + 1.523 +int 1.524 +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) 1.525 + int argc; 1.526 + char *const *argv; 1.527 + const char *optstring; 1.528 + const struct option *longopts; 1.529 + int *longind; 1.530 + int long_only; 1.531 +{ 1.532 + optarg = NULL; 1.533 + 1.534 + if (optind == 0 || !__getopt_initialized) 1.535 + { 1.536 + if (optind == 0) 1.537 + optind = 1; /* Don't scan ARGV[0], the program name. */ 1.538 + optstring = _getopt_initialize (argc, argv, optstring); 1.539 + __getopt_initialized = 1; 1.540 + } 1.541 + 1.542 + /* Test whether ARGV[optind] points to a non-option argument. 1.543 + Either it does not have option syntax, or there is an environment flag 1.544 + from the shell indicating it is not an option. The later information 1.545 + is only used when the used in the GNU libc. */ 1.546 +#ifdef _LIBC 1.547 +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ 1.548 + || (optind < nonoption_flags_len \ 1.549 + && __getopt_nonoption_flags[optind] == '1')) 1.550 +#else 1.551 +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') 1.552 +#endif 1.553 + 1.554 + if (nextchar == NULL || *nextchar == '\0') 1.555 + { 1.556 + /* Advance to the next ARGV-element. */ 1.557 + 1.558 + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been 1.559 + moved back by the user (who may also have changed the arguments). */ 1.560 + if (last_nonopt > optind) 1.561 + last_nonopt = optind; 1.562 + if (first_nonopt > optind) 1.563 + first_nonopt = optind; 1.564 + 1.565 + if (ordering == PERMUTE) 1.566 + { 1.567 + /* If we have just processed some options following some non-options, 1.568 + exchange them so that the options come first. */ 1.569 + 1.570 + if (first_nonopt != last_nonopt && last_nonopt != optind) 1.571 + exchange ((char **) argv); 1.572 + else if (last_nonopt != optind) 1.573 + first_nonopt = optind; 1.574 + 1.575 + /* Skip any additional non-options 1.576 + and extend the range of non-options previously skipped. */ 1.577 + 1.578 + while (optind < argc && NONOPTION_P) 1.579 + optind++; 1.580 + last_nonopt = optind; 1.581 + } 1.582 + 1.583 + /* The special ARGV-element `--' means premature end of options. 1.584 + Skip it like a null option, 1.585 + then exchange with previous non-options as if it were an option, 1.586 + then skip everything else like a non-option. */ 1.587 + 1.588 + if (optind != argc && !strcmp (argv[optind], "--")) 1.589 + { 1.590 + optind++; 1.591 + 1.592 + if (first_nonopt != last_nonopt && last_nonopt != optind) 1.593 + exchange ((char **) argv); 1.594 + else if (first_nonopt == last_nonopt) 1.595 + first_nonopt = optind; 1.596 + last_nonopt = argc; 1.597 + 1.598 + optind = argc; 1.599 + } 1.600 + 1.601 + /* If we have done all the ARGV-elements, stop the scan 1.602 + and back over any non-options that we skipped and permuted. */ 1.603 + 1.604 + if (optind == argc) 1.605 + { 1.606 + /* Set the next-arg-index to point at the non-options 1.607 + that we previously skipped, so the caller will digest them. */ 1.608 + if (first_nonopt != last_nonopt) 1.609 + optind = first_nonopt; 1.610 + return -1; 1.611 + } 1.612 + 1.613 + /* If we have come to a non-option and did not permute it, 1.614 + either stop the scan or describe it to the caller and pass it by. */ 1.615 + 1.616 + if (NONOPTION_P) 1.617 + { 1.618 + if (ordering == REQUIRE_ORDER) 1.619 + return -1; 1.620 + optarg = argv[optind++]; 1.621 + return 1; 1.622 + } 1.623 + 1.624 + /* We have found another option-ARGV-element. 1.625 + Skip the initial punctuation. */ 1.626 + 1.627 + nextchar = (argv[optind] + 1 1.628 + + (longopts != NULL && argv[optind][1] == '-')); 1.629 + } 1.630 + 1.631 + /* Decode the current option-ARGV-element. */ 1.632 + 1.633 + /* Check whether the ARGV-element is a long option. 1.634 + 1.635 + If long_only and the ARGV-element has the form "-f", where f is 1.636 + a valid short option, don't consider it an abbreviated form of 1.637 + a long option that starts with f. Otherwise there would be no 1.638 + way to give the -f short option. 1.639 + 1.640 + On the other hand, if there's a long option "fubar" and 1.641 + the ARGV-element is "-fu", do consider that an abbreviation of 1.642 + the long option, just like "--fu", and not "-f" with arg "u". 1.643 + 1.644 + This distinction seems to be the most useful approach. */ 1.645 + 1.646 + if (longopts != NULL 1.647 + && (argv[optind][1] == '-' 1.648 + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) 1.649 + { 1.650 + char *nameend; 1.651 + const struct option *p; 1.652 + const struct option *pfound = NULL; 1.653 + int exact = 0; 1.654 + int ambig = 0; 1.655 + int indfound = -1; 1.656 + int option_index; 1.657 + 1.658 + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) 1.659 + /* Do nothing. */ ; 1.660 + 1.661 + /* Test all long options for either exact match 1.662 + or abbreviated matches. */ 1.663 + for (p = longopts, option_index = 0; p->name; p++, option_index++) 1.664 + if (!strncmp (p->name, nextchar, nameend - nextchar)) 1.665 + { 1.666 + if ((unsigned int) (nameend - nextchar) 1.667 + == (unsigned int) strlen (p->name)) 1.668 + { 1.669 + /* Exact match found. */ 1.670 + pfound = p; 1.671 + indfound = option_index; 1.672 + exact = 1; 1.673 + break; 1.674 + } 1.675 + else if (pfound == NULL) 1.676 + { 1.677 + /* First nonexact match found. */ 1.678 + pfound = p; 1.679 + indfound = option_index; 1.680 + } 1.681 + else 1.682 + /* Second or later nonexact match found. */ 1.683 + ambig = 1; 1.684 + } 1.685 + 1.686 + if (ambig && !exact) 1.687 + { 1.688 + if (opterr) 1.689 + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), 1.690 + argv[0], argv[optind]); 1.691 + nextchar += strlen (nextchar); 1.692 + optind++; 1.693 + optopt = 0; 1.694 + return '?'; 1.695 + } 1.696 + 1.697 + if (pfound != NULL) 1.698 + { 1.699 + option_index = indfound; 1.700 + optind++; 1.701 + if (*nameend) 1.702 + { 1.703 + /* Don't test has_arg with >, because some C compilers don't 1.704 + allow it to be used on enums. */ 1.705 + if (pfound->has_arg) 1.706 + optarg = nameend + 1; 1.707 + else 1.708 + { 1.709 + if (opterr) 1.710 + { 1.711 + if (argv[optind - 1][1] == '-') 1.712 + /* --option */ 1.713 + fprintf (stderr, 1.714 + _("%s: option `--%s' doesn't allow an argument\n"), 1.715 + argv[0], pfound->name); 1.716 + else 1.717 + /* +option or -option */ 1.718 + fprintf (stderr, 1.719 + _("%s: option `%c%s' doesn't allow an argument\n"), 1.720 + argv[0], argv[optind - 1][0], pfound->name); 1.721 + 1.722 + nextchar += strlen (nextchar); 1.723 + 1.724 + optopt = pfound->val; 1.725 + return '?'; 1.726 + } 1.727 + } 1.728 + } 1.729 + else if (pfound->has_arg == 1) 1.730 + { 1.731 + if (optind < argc) 1.732 + optarg = argv[optind++]; 1.733 + else 1.734 + { 1.735 + if (opterr) 1.736 + fprintf (stderr, 1.737 + _("%s: option `%s' requires an argument\n"), 1.738 + argv[0], argv[optind - 1]); 1.739 + nextchar += strlen (nextchar); 1.740 + optopt = pfound->val; 1.741 + return optstring[0] == ':' ? ':' : '?'; 1.742 + } 1.743 + } 1.744 + nextchar += strlen (nextchar); 1.745 + if (longind != NULL) 1.746 + *longind = option_index; 1.747 + if (pfound->flag) 1.748 + { 1.749 + *(pfound->flag) = pfound->val; 1.750 + return 0; 1.751 + } 1.752 + return pfound->val; 1.753 + } 1.754 + 1.755 + /* Can't find it as a long option. If this is not getopt_long_only, 1.756 + or the option starts with '--' or is not a valid short 1.757 + option, then it's an error. 1.758 + Otherwise interpret it as a short option. */ 1.759 + if (!long_only || argv[optind][1] == '-' 1.760 + || my_index (optstring, *nextchar) == NULL) 1.761 + { 1.762 + if (opterr) 1.763 + { 1.764 + if (argv[optind][1] == '-') 1.765 + /* --option */ 1.766 + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), 1.767 + argv[0], nextchar); 1.768 + else 1.769 + /* +option or -option */ 1.770 + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), 1.771 + argv[0], argv[optind][0], nextchar); 1.772 + } 1.773 + nextchar = (char *) ""; 1.774 + optind++; 1.775 + optopt = 0; 1.776 + return '?'; 1.777 + } 1.778 + } 1.779 + 1.780 + /* Look at and handle the next short option-character. */ 1.781 + 1.782 + { 1.783 + char c = *nextchar++; 1.784 + char *temp = my_index (optstring, c); 1.785 + 1.786 + /* Increment `optind' when we start to process its last character. */ 1.787 + if (*nextchar == '\0') 1.788 + ++optind; 1.789 + 1.790 + if (temp == NULL || c == ':') 1.791 + { 1.792 + if (opterr) 1.793 + { 1.794 + if (posixly_correct) 1.795 + /* 1003.2 specifies the format of this message. */ 1.796 + fprintf (stderr, _("%s: illegal option -- %c\n"), 1.797 + argv[0], c); 1.798 + else 1.799 + fprintf (stderr, _("%s: invalid option -- %c\n"), 1.800 + argv[0], c); 1.801 + } 1.802 + optopt = c; 1.803 + return '?'; 1.804 + } 1.805 + /* Convenience. Treat POSIX -W foo same as long option --foo */ 1.806 + if (temp[0] == 'W' && temp[1] == ';') 1.807 + { 1.808 + char *nameend; 1.809 + const struct option *p; 1.810 + const struct option *pfound = NULL; 1.811 + int exact = 0; 1.812 + int ambig = 0; 1.813 + int indfound = 0; 1.814 + int option_index; 1.815 + 1.816 + /* This is an option that requires an argument. */ 1.817 + if (*nextchar != '\0') 1.818 + { 1.819 + optarg = nextchar; 1.820 + /* If we end this ARGV-element by taking the rest as an arg, 1.821 + we must advance to the next element now. */ 1.822 + optind++; 1.823 + } 1.824 + else if (optind == argc) 1.825 + { 1.826 + if (opterr) 1.827 + { 1.828 + /* 1003.2 specifies the format of this message. */ 1.829 + fprintf (stderr, _("%s: option requires an argument -- %c\n"), 1.830 + argv[0], c); 1.831 + } 1.832 + optopt = c; 1.833 + if (optstring[0] == ':') 1.834 + c = ':'; 1.835 + else 1.836 + c = '?'; 1.837 + return c; 1.838 + } 1.839 + else 1.840 + /* We already incremented `optind' once; 1.841 + increment it again when taking next ARGV-elt as argument. */ 1.842 + optarg = argv[optind++]; 1.843 + 1.844 + /* optarg is now the argument, see if it's in the 1.845 + table of longopts. */ 1.846 + 1.847 + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) 1.848 + /* Do nothing. */ ; 1.849 + 1.850 + /* Test all long options for either exact match 1.851 + or abbreviated matches. */ 1.852 + for (p = longopts, option_index = 0; p->name; p++, option_index++) 1.853 + if (!strncmp (p->name, nextchar, nameend - nextchar)) 1.854 + { 1.855 + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) 1.856 + { 1.857 + /* Exact match found. */ 1.858 + pfound = p; 1.859 + indfound = option_index; 1.860 + exact = 1; 1.861 + break; 1.862 + } 1.863 + else if (pfound == NULL) 1.864 + { 1.865 + /* First nonexact match found. */ 1.866 + pfound = p; 1.867 + indfound = option_index; 1.868 + } 1.869 + else 1.870 + /* Second or later nonexact match found. */ 1.871 + ambig = 1; 1.872 + } 1.873 + if (ambig && !exact) 1.874 + { 1.875 + if (opterr) 1.876 + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), 1.877 + argv[0], argv[optind]); 1.878 + nextchar += strlen (nextchar); 1.879 + optind++; 1.880 + return '?'; 1.881 + } 1.882 + if (pfound != NULL) 1.883 + { 1.884 + option_index = indfound; 1.885 + if (*nameend) 1.886 + { 1.887 + /* Don't test has_arg with >, because some C compilers don't 1.888 + allow it to be used on enums. */ 1.889 + if (pfound->has_arg) 1.890 + optarg = nameend + 1; 1.891 + else 1.892 + { 1.893 + if (opterr) 1.894 + fprintf (stderr, _("\ 1.895 +%s: option `-W %s' doesn't allow an argument\n"), 1.896 + argv[0], pfound->name); 1.897 + 1.898 + nextchar += strlen (nextchar); 1.899 + return '?'; 1.900 + } 1.901 + } 1.902 + else if (pfound->has_arg == 1) 1.903 + { 1.904 + if (optind < argc) 1.905 + optarg = argv[optind++]; 1.906 + else 1.907 + { 1.908 + if (opterr) 1.909 + fprintf (stderr, 1.910 + _("%s: option `%s' requires an argument\n"), 1.911 + argv[0], argv[optind - 1]); 1.912 + nextchar += strlen (nextchar); 1.913 + return optstring[0] == ':' ? ':' : '?'; 1.914 + } 1.915 + } 1.916 + nextchar += strlen (nextchar); 1.917 + if (longind != NULL) 1.918 + *longind = option_index; 1.919 + if (pfound->flag) 1.920 + { 1.921 + *(pfound->flag) = pfound->val; 1.922 + return 0; 1.923 + } 1.924 + return pfound->val; 1.925 + } 1.926 + nextchar = NULL; 1.927 + return 'W'; /* Let the application handle it. */ 1.928 + } 1.929 + if (temp[1] == ':') 1.930 + { 1.931 + if (temp[2] == ':') 1.932 + { 1.933 + /* This is an option that accepts an argument optionally. */ 1.934 + if (*nextchar != '\0') 1.935 + { 1.936 + optarg = nextchar; 1.937 + optind++; 1.938 + } 1.939 + else 1.940 + optarg = NULL; 1.941 + nextchar = NULL; 1.942 + } 1.943 + else 1.944 + { 1.945 + /* This is an option that requires an argument. */ 1.946 + if (*nextchar != '\0') 1.947 + { 1.948 + optarg = nextchar; 1.949 + /* If we end this ARGV-element by taking the rest as an arg, 1.950 + we must advance to the next element now. */ 1.951 + optind++; 1.952 + } 1.953 + else if (optind == argc) 1.954 + { 1.955 + if (opterr) 1.956 + { 1.957 + /* 1003.2 specifies the format of this message. */ 1.958 + fprintf (stderr, 1.959 + _("%s: option requires an argument -- %c\n"), 1.960 + argv[0], c); 1.961 + } 1.962 + optopt = c; 1.963 + if (optstring[0] == ':') 1.964 + c = ':'; 1.965 + else 1.966 + c = '?'; 1.967 + } 1.968 + else 1.969 + /* We already incremented `optind' once; 1.970 + increment it again when taking next ARGV-elt as argument. */ 1.971 + optarg = argv[optind++]; 1.972 + nextchar = NULL; 1.973 + } 1.974 + } 1.975 + return c; 1.976 + } 1.977 +} 1.978 + 1.979 +int 1.980 +getopt (argc, argv, optstring) 1.981 + int argc; 1.982 + char *const *argv; 1.983 + const char *optstring; 1.984 +{ 1.985 + return _getopt_internal (argc, argv, optstring, 1.986 + (const struct option *) 0, 1.987 + (int *) 0, 1.988 + 0); 1.989 +} 1.990 + 1.991 +#endif /* Not ELIDE_CODE. */ 1.992 + 1.993 +#ifdef TEST 1.994 + 1.995 +/* Compile with -DTEST to make an executable for use in testing 1.996 + the above definition of `getopt'. */ 1.997 + 1.998 +int 1.999 +main (argc, argv) 1.1000 + int argc; 1.1001 + char **argv; 1.1002 +{ 1.1003 + int c; 1.1004 + int digit_optind = 0; 1.1005 + 1.1006 + while (1) 1.1007 + { 1.1008 + int this_option_optind = optind ? optind : 1; 1.1009 + 1.1010 + c = getopt (argc, argv, "abc:d:0123456789"); 1.1011 + if (c == -1) 1.1012 + break; 1.1013 + 1.1014 + switch (c) 1.1015 + { 1.1016 + case '0': 1.1017 + case '1': 1.1018 + case '2': 1.1019 + case '3': 1.1020 + case '4': 1.1021 + case '5': 1.1022 + case '6': 1.1023 + case '7': 1.1024 + case '8': 1.1025 + case '9': 1.1026 + if (digit_optind != 0 && digit_optind != this_option_optind) 1.1027 + printf ("digits occur in two different argv-elements.\n"); 1.1028 + digit_optind = this_option_optind; 1.1029 + printf ("option %c\n", c); 1.1030 + break; 1.1031 + 1.1032 + case 'a': 1.1033 + printf ("option a\n"); 1.1034 + break; 1.1035 + 1.1036 + case 'b': 1.1037 + printf ("option b\n"); 1.1038 + break; 1.1039 + 1.1040 + case 'c': 1.1041 + printf ("option c with value `%s'\n", optarg); 1.1042 + break; 1.1043 + 1.1044 + case '?': 1.1045 + break; 1.1046 + 1.1047 + default: 1.1048 + printf ("?? getopt returned character code 0%o ??\n", c); 1.1049 + } 1.1050 + } 1.1051 + 1.1052 + if (optind < argc) 1.1053 + { 1.1054 + printf ("non-option ARGV-elements: "); 1.1055 + while (optind < argc) 1.1056 + printf ("%s ", argv[optind++]); 1.1057 + printf ("\n"); 1.1058 + } 1.1059 + 1.1060 + exit (0); 1.1061 +} 1.1062 + 1.1063 +#endif /* TEST */