annotate src/sdl/getopt.c @ 280:d5e5c73af7e6

reorginazed save corruption code
author Robert McIntyre <rlm@mit.edu>
date Tue, 27 Mar 2012 21:08:44 -0500
parents f9f4f1b99eed
children
rev   line source
rlm@1 1 /* Getopt for GNU.
rlm@1 2 NOTE: getopt is now part of the C library, so if you don't know what
rlm@1 3 "Keep this file name-space clean" means, talk to drepper@gnu.org
rlm@1 4 before changing it!
rlm@1 5
rlm@1 6 Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
rlm@1 7 Free Software Foundation, Inc.
rlm@1 8
rlm@1 9 NOTE: This source is derived from an old version taken from the GNU C
rlm@1 10 Library (glibc).
rlm@1 11
rlm@1 12 This program is free software; you can redistribute it and/or modify it
rlm@1 13 under the terms of the GNU General Public License as published by the
rlm@1 14 Free Software Foundation; either version 2, or (at your option) any
rlm@1 15 later version.
rlm@1 16
rlm@1 17 This program is distributed in the hope that it will be useful,
rlm@1 18 but WITHOUT ANY WARRANTY; without even the implied warranty of
rlm@1 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
rlm@1 20 GNU General Public License for more details.
rlm@1 21
rlm@1 22 You should have received a copy of the GNU General Public License
rlm@1 23 along with this program; if not, write to the Free Software
rlm@1 24 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
rlm@1 25 USA. */
rlm@1 26
rlm@1 27 /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
rlm@1 28 Ditto for AIX 3.2 and <stdlib.h>. */
rlm@1 29 #ifndef _NO_PROTO
rlm@1 30 # define _NO_PROTO
rlm@1 31 #endif
rlm@1 32
rlm@1 33 #ifdef HAVE_CONFIG_H
rlm@1 34 # include <config.h>
rlm@1 35 #endif
rlm@1 36
rlm@1 37 #if !defined __STDC__ || !__STDC__
rlm@1 38 /* This is a separate conditional since some stdc systems
rlm@1 39 reject `defined (const)'. */
rlm@1 40 # ifndef const
rlm@1 41 # define const
rlm@1 42 # endif
rlm@1 43 #endif
rlm@1 44
rlm@1 45 #include <stdio.h>
rlm@1 46
rlm@1 47 /* Comment out all this code if we are using the GNU C Library, and are not
rlm@1 48 actually compiling the library itself. This code is part of the GNU C
rlm@1 49 Library, but also included in many other GNU distributions. Compiling
rlm@1 50 and linking in this code is a waste when using the GNU C library
rlm@1 51 (especially if it is a shared library). Rather than having every GNU
rlm@1 52 program understand `configure --with-gnu-libc' and omit the object files,
rlm@1 53 it is simpler to just do this in the source for each such file. */
rlm@1 54
rlm@1 55 #define GETOPT_INTERFACE_VERSION 2
rlm@1 56 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
rlm@1 57 # include <gnu-versions.h>
rlm@1 58 # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
rlm@1 59 # define ELIDE_CODE
rlm@1 60 # endif
rlm@1 61 #endif
rlm@1 62
rlm@1 63 #ifndef ELIDE_CODE
rlm@1 64
rlm@1 65
rlm@1 66 /* This needs to come after some library #include
rlm@1 67 to get __GNU_LIBRARY__ defined. */
rlm@1 68 #ifdef __GNU_LIBRARY__
rlm@1 69 /* Don't include stdlib.h for non-GNU C libraries because some of them
rlm@1 70 contain conflicting prototypes for getopt. */
rlm@1 71 # include <stdlib.h>
rlm@1 72 # include <unistd.h>
rlm@1 73 #endif /* GNU C library. */
rlm@1 74
rlm@1 75 #ifdef VMS
rlm@1 76 # include <unixlib.h>
rlm@1 77 # if HAVE_STRING_H - 0
rlm@1 78 # include <string.h>
rlm@1 79 # endif
rlm@1 80 #endif
rlm@1 81
rlm@1 82 #ifndef _
rlm@1 83 /* This is for other GNU distributions with internationalized messages.
rlm@1 84 When compiling libc, the _ macro is predefined. */
rlm@1 85 # ifdef HAVE_LIBINTL_H
rlm@1 86 # include <libintl.h>
rlm@1 87 # define _(msgid) gettext (msgid)
rlm@1 88 # else
rlm@1 89 # define _(msgid) (msgid)
rlm@1 90 # endif
rlm@1 91 #endif
rlm@1 92
rlm@1 93 #ifdef _MSC_VER
rlm@1 94 #include <string.h>
rlm@1 95 #endif
rlm@1 96
rlm@1 97 /* This version of `getopt' appears to the caller like standard Unix `getopt'
rlm@1 98 but it behaves differently for the user, since it allows the user
rlm@1 99 to intersperse the options with the other arguments.
rlm@1 100
rlm@1 101 As `getopt' works, it permutes the elements of ARGV so that,
rlm@1 102 when it is done, all the options precede everything else. Thus
rlm@1 103 all application programs are extended to handle flexible argument order.
rlm@1 104
rlm@1 105 Setting the environment variable POSIXLY_CORRECT disables permutation.
rlm@1 106 Then the behavior is completely standard.
rlm@1 107
rlm@1 108 GNU application programs can use a third alternative mode in which
rlm@1 109 they can distinguish the relative order of options and other arguments. */
rlm@1 110
rlm@1 111 #include "getopt.h"
rlm@1 112
rlm@1 113 /* For communication from `getopt' to the caller.
rlm@1 114 When `getopt' finds an option that takes an argument,
rlm@1 115 the argument value is returned here.
rlm@1 116 Also, when `ordering' is RETURN_IN_ORDER,
rlm@1 117 each non-option ARGV-element is returned here. */
rlm@1 118
rlm@1 119 char *optarg = NULL;
rlm@1 120
rlm@1 121 /* Index in ARGV of the next element to be scanned.
rlm@1 122 This is used for communication to and from the caller
rlm@1 123 and for communication between successive calls to `getopt'.
rlm@1 124
rlm@1 125 On entry to `getopt', zero means this is the first call; initialize.
rlm@1 126
rlm@1 127 When `getopt' returns -1, this is the index of the first of the
rlm@1 128 non-option elements that the caller should itself scan.
rlm@1 129
rlm@1 130 Otherwise, `optind' communicates from one call to the next
rlm@1 131 how much of ARGV has been scanned so far. */
rlm@1 132
rlm@1 133 /* 1003.2 says this must be 1 before any call. */
rlm@1 134 int optind = 1;
rlm@1 135
rlm@1 136 /* Formerly, initialization of getopt depended on optind==0, which
rlm@1 137 causes problems with re-calling getopt as programs generally don't
rlm@1 138 know that. */
rlm@1 139
rlm@1 140 int __getopt_initialized = 0;
rlm@1 141
rlm@1 142 /* The next char to be scanned in the option-element
rlm@1 143 in which the last option character we returned was found.
rlm@1 144 This allows us to pick up the scan where we left off.
rlm@1 145
rlm@1 146 If this is zero, or a null string, it means resume the scan
rlm@1 147 by advancing to the next ARGV-element. */
rlm@1 148
rlm@1 149 static char *nextchar;
rlm@1 150
rlm@1 151 /* Callers store zero here to inhibit the error message
rlm@1 152 for unrecognized options. */
rlm@1 153
rlm@1 154 int opterr = 1;
rlm@1 155
rlm@1 156 /* Set to an option character which was unrecognized.
rlm@1 157 This must be initialized on some systems to avoid linking in the
rlm@1 158 system's own getopt implementation. */
rlm@1 159
rlm@1 160 int optopt = '?';
rlm@1 161
rlm@1 162 /* Describe how to deal with options that follow non-option ARGV-elements.
rlm@1 163
rlm@1 164 If the caller did not specify anything,
rlm@1 165 the default is REQUIRE_ORDER if the environment variable
rlm@1 166 POSIXLY_CORRECT is defined, PERMUTE otherwise.
rlm@1 167
rlm@1 168 REQUIRE_ORDER means don't recognize them as options;
rlm@1 169 stop option processing when the first non-option is seen.
rlm@1 170 This is what Unix does.
rlm@1 171 This mode of operation is selected by either setting the environment
rlm@1 172 variable POSIXLY_CORRECT, or using `+' as the first character
rlm@1 173 of the list of option characters.
rlm@1 174
rlm@1 175 PERMUTE is the default. We permute the contents of ARGV as we scan,
rlm@1 176 so that eventually all the non-options are at the end. This allows options
rlm@1 177 to be given in any order, even with programs that were not written to
rlm@1 178 expect this.
rlm@1 179
rlm@1 180 RETURN_IN_ORDER is an option available to programs that were written
rlm@1 181 to expect options and other ARGV-elements in any order and that care about
rlm@1 182 the ordering of the two. We describe each non-option ARGV-element
rlm@1 183 as if it were the argument of an option with character code 1.
rlm@1 184 Using `-' as the first character of the list of option characters
rlm@1 185 selects this mode of operation.
rlm@1 186
rlm@1 187 The special argument `--' forces an end of option-scanning regardless
rlm@1 188 of the value of `ordering'. In the case of RETURN_IN_ORDER, only
rlm@1 189 `--' can cause `getopt' to return -1 with `optind' != ARGC. */
rlm@1 190
rlm@1 191 static enum
rlm@1 192 {
rlm@1 193 REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
rlm@1 194 } ordering;
rlm@1 195
rlm@1 196 /* Value of POSIXLY_CORRECT environment variable. */
rlm@1 197 static char *posixly_correct;
rlm@1 198
rlm@1 199 #ifdef __GNU_LIBRARY__
rlm@1 200 /* We want to avoid inclusion of string.h with non-GNU libraries
rlm@1 201 because there are many ways it can cause trouble.
rlm@1 202 On some systems, it contains special magic macros that don't work
rlm@1 203 in GCC. */
rlm@1 204 # include <string.h>
rlm@1 205 # define my_index strchr
rlm@1 206 #else
rlm@1 207
rlm@1 208 # if HAVE_STRING_H
rlm@1 209 # include <string.h>
rlm@1 210 # else
rlm@1 211 # if HAVE_STRINGS_H
rlm@1 212 # include <strings.h>
rlm@1 213 # endif
rlm@1 214 # endif
rlm@1 215
rlm@1 216 /* Avoid depending on library functions or files
rlm@1 217 whose names are inconsistent. */
rlm@1 218
rlm@1 219 #ifndef getenv
rlm@1 220 extern char *getenv ();
rlm@1 221 #endif
rlm@1 222
rlm@1 223 static char *
rlm@1 224 my_index (str, chr)
rlm@1 225 const char *str;
rlm@1 226 int chr;
rlm@1 227 {
rlm@1 228 while (*str)
rlm@1 229 {
rlm@1 230 if (*str == chr)
rlm@1 231 return (char *) str;
rlm@1 232 str++;
rlm@1 233 }
rlm@1 234 return 0;
rlm@1 235 }
rlm@1 236
rlm@1 237 /* If using GCC, we can safely declare strlen this way.
rlm@1 238 If not using GCC, it is ok not to declare it. */
rlm@1 239 #ifdef __GNUC__
rlm@1 240 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
rlm@1 241 That was relevant to code that was here before. */
rlm@1 242 # if (!defined __STDC__ || !__STDC__) && !defined strlen
rlm@1 243 /* gcc with -traditional declares the built-in strlen to return int,
rlm@1 244 and has done so at least since version 2.4.5. -- rms. */
rlm@1 245 extern int strlen (const char *);
rlm@1 246 # endif /* not __STDC__ */
rlm@1 247 #endif /* __GNUC__ */
rlm@1 248
rlm@1 249 #endif /* not __GNU_LIBRARY__ */
rlm@1 250
rlm@1 251 /* Handle permutation of arguments. */
rlm@1 252
rlm@1 253 /* Describe the part of ARGV that contains non-options that have
rlm@1 254 been skipped. `first_nonopt' is the index in ARGV of the first of them;
rlm@1 255 `last_nonopt' is the index after the last of them. */
rlm@1 256
rlm@1 257 static int first_nonopt;
rlm@1 258 static int last_nonopt;
rlm@1 259
rlm@1 260 #ifdef _LIBC
rlm@1 261 /* Bash 2.0 gives us an environment variable containing flags
rlm@1 262 indicating ARGV elements that should not be considered arguments. */
rlm@1 263
rlm@1 264 /* Defined in getopt_init.c */
rlm@1 265 extern char *__getopt_nonoption_flags;
rlm@1 266
rlm@1 267 static int nonoption_flags_max_len;
rlm@1 268 static int nonoption_flags_len;
rlm@1 269
rlm@1 270 static int original_argc;
rlm@1 271 static char *const *original_argv;
rlm@1 272
rlm@1 273 /* Make sure the environment variable bash 2.0 puts in the environment
rlm@1 274 is valid for the getopt call we must make sure that the ARGV passed
rlm@1 275 to getopt is that one passed to the process. */
rlm@1 276 static void
rlm@1 277 __attribute__ ((unused))
rlm@1 278 store_args_and_env (int argc, char *const *argv)
rlm@1 279 {
rlm@1 280 /* XXX This is no good solution. We should rather copy the args so
rlm@1 281 that we can compare them later. But we must not use malloc(3). */
rlm@1 282 original_argc = argc;
rlm@1 283 original_argv = argv;
rlm@1 284 }
rlm@1 285 # ifdef text_set_element
rlm@1 286 text_set_element (__libc_subinit, store_args_and_env);
rlm@1 287 # endif /* text_set_element */
rlm@1 288
rlm@1 289 # define SWAP_FLAGS(ch1, ch2) \
rlm@1 290 if (nonoption_flags_len > 0) \
rlm@1 291 { \
rlm@1 292 char __tmp = __getopt_nonoption_flags[ch1]; \
rlm@1 293 __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
rlm@1 294 __getopt_nonoption_flags[ch2] = __tmp; \
rlm@1 295 }
rlm@1 296 #else /* !_LIBC */
rlm@1 297 # define SWAP_FLAGS(ch1, ch2)
rlm@1 298 #endif /* _LIBC */
rlm@1 299
rlm@1 300 /* Exchange two adjacent subsequences of ARGV.
rlm@1 301 One subsequence is elements [first_nonopt,last_nonopt)
rlm@1 302 which contains all the non-options that have been skipped so far.
rlm@1 303 The other is elements [last_nonopt,optind), which contains all
rlm@1 304 the options processed since those non-options were skipped.
rlm@1 305
rlm@1 306 `first_nonopt' and `last_nonopt' are relocated so that they describe
rlm@1 307 the new indices of the non-options in ARGV after they are moved. */
rlm@1 308
rlm@1 309 #if defined __STDC__ && __STDC__
rlm@1 310 static void exchange (char **);
rlm@1 311 #endif
rlm@1 312
rlm@1 313 static void
rlm@1 314 exchange (argv)
rlm@1 315 char **argv;
rlm@1 316 {
rlm@1 317 int bottom = first_nonopt;
rlm@1 318 int middle = last_nonopt;
rlm@1 319 int top = optind;
rlm@1 320 char *tem;
rlm@1 321
rlm@1 322 /* Exchange the shorter segment with the far end of the longer segment.
rlm@1 323 That puts the shorter segment into the right place.
rlm@1 324 It leaves the longer segment in the right place overall,
rlm@1 325 but it consists of two parts that need to be swapped next. */
rlm@1 326
rlm@1 327 #ifdef _LIBC
rlm@1 328 /* First make sure the handling of the `__getopt_nonoption_flags'
rlm@1 329 string can work normally. Our top argument must be in the range
rlm@1 330 of the string. */
rlm@1 331 if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
rlm@1 332 {
rlm@1 333 /* We must extend the array. The user plays games with us and
rlm@1 334 presents new arguments. */
rlm@1 335 char *new_str = malloc (top + 1);
rlm@1 336 if (new_str == NULL)
rlm@1 337 nonoption_flags_len = nonoption_flags_max_len = 0;
rlm@1 338 else
rlm@1 339 {
rlm@1 340 memset (__mempcpy (new_str, __getopt_nonoption_flags,
rlm@1 341 nonoption_flags_max_len),
rlm@1 342 '\0', top + 1 - nonoption_flags_max_len);
rlm@1 343 nonoption_flags_max_len = top + 1;
rlm@1 344 __getopt_nonoption_flags = new_str;
rlm@1 345 }
rlm@1 346 }
rlm@1 347 #endif
rlm@1 348
rlm@1 349 while (top > middle && middle > bottom)
rlm@1 350 {
rlm@1 351 if (top - middle > middle - bottom)
rlm@1 352 {
rlm@1 353 /* Bottom segment is the short one. */
rlm@1 354 int len = middle - bottom;
rlm@1 355 register int i;
rlm@1 356
rlm@1 357 /* Swap it with the top part of the top segment. */
rlm@1 358 for (i = 0; i < len; i++)
rlm@1 359 {
rlm@1 360 tem = argv[bottom + i];
rlm@1 361 argv[bottom + i] = argv[top - (middle - bottom) + i];
rlm@1 362 argv[top - (middle - bottom) + i] = tem;
rlm@1 363 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
rlm@1 364 }
rlm@1 365 /* Exclude the moved bottom segment from further swapping. */
rlm@1 366 top -= len;
rlm@1 367 }
rlm@1 368 else
rlm@1 369 {
rlm@1 370 /* Top segment is the short one. */
rlm@1 371 int len = top - middle;
rlm@1 372 register int i;
rlm@1 373
rlm@1 374 /* Swap it with the bottom part of the bottom segment. */
rlm@1 375 for (i = 0; i < len; i++)
rlm@1 376 {
rlm@1 377 tem = argv[bottom + i];
rlm@1 378 argv[bottom + i] = argv[middle + i];
rlm@1 379 argv[middle + i] = tem;
rlm@1 380 SWAP_FLAGS (bottom + i, middle + i);
rlm@1 381 }
rlm@1 382 /* Exclude the moved top segment from further swapping. */
rlm@1 383 bottom += len;
rlm@1 384 }
rlm@1 385 }
rlm@1 386
rlm@1 387 /* Update records for the slots the non-options now occupy. */
rlm@1 388
rlm@1 389 first_nonopt += (optind - last_nonopt);
rlm@1 390 last_nonopt = optind;
rlm@1 391 }
rlm@1 392
rlm@1 393 /* Initialize the internal data when the first call is made. */
rlm@1 394
rlm@1 395 #if defined __STDC__ && __STDC__
rlm@1 396 static const char *_getopt_initialize (int, char *const *, const char *);
rlm@1 397 #endif
rlm@1 398 static const char *
rlm@1 399 _getopt_initialize (argc, argv, optstring)
rlm@1 400 int argc;
rlm@1 401 char *const *argv;
rlm@1 402 const char *optstring;
rlm@1 403 {
rlm@1 404 /* Start processing options with ARGV-element 1 (since ARGV-element 0
rlm@1 405 is the program name); the sequence of previously skipped
rlm@1 406 non-option ARGV-elements is empty. */
rlm@1 407
rlm@1 408 first_nonopt = last_nonopt = optind;
rlm@1 409
rlm@1 410 nextchar = NULL;
rlm@1 411
rlm@1 412 posixly_correct = getenv ("POSIXLY_CORRECT");
rlm@1 413
rlm@1 414 /* Determine how to handle the ordering of options and nonoptions. */
rlm@1 415
rlm@1 416 if (optstring[0] == '-')
rlm@1 417 {
rlm@1 418 ordering = RETURN_IN_ORDER;
rlm@1 419 ++optstring;
rlm@1 420 }
rlm@1 421 else if (optstring[0] == '+')
rlm@1 422 {
rlm@1 423 ordering = REQUIRE_ORDER;
rlm@1 424 ++optstring;
rlm@1 425 }
rlm@1 426 else if (posixly_correct != NULL)
rlm@1 427 ordering = REQUIRE_ORDER;
rlm@1 428 else
rlm@1 429 ordering = PERMUTE;
rlm@1 430
rlm@1 431 #ifdef _LIBC
rlm@1 432 if (posixly_correct == NULL
rlm@1 433 && argc == original_argc && argv == original_argv)
rlm@1 434 {
rlm@1 435 if (nonoption_flags_max_len == 0)
rlm@1 436 {
rlm@1 437 if (__getopt_nonoption_flags == NULL
rlm@1 438 || __getopt_nonoption_flags[0] == '\0')
rlm@1 439 nonoption_flags_max_len = -1;
rlm@1 440 else
rlm@1 441 {
rlm@1 442 const char *orig_str = __getopt_nonoption_flags;
rlm@1 443 int len = nonoption_flags_max_len = strlen (orig_str);
rlm@1 444 if (nonoption_flags_max_len < argc)
rlm@1 445 nonoption_flags_max_len = argc;
rlm@1 446 __getopt_nonoption_flags =
rlm@1 447 (char *) malloc (nonoption_flags_max_len);
rlm@1 448 if (__getopt_nonoption_flags == NULL)
rlm@1 449 nonoption_flags_max_len = -1;
rlm@1 450 else
rlm@1 451 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
rlm@1 452 '\0', nonoption_flags_max_len - len);
rlm@1 453 }
rlm@1 454 }
rlm@1 455 nonoption_flags_len = nonoption_flags_max_len;
rlm@1 456 }
rlm@1 457 else
rlm@1 458 nonoption_flags_len = 0;
rlm@1 459 #endif
rlm@1 460
rlm@1 461 return optstring;
rlm@1 462 }
rlm@1 463
rlm@1 464 /* Scan elements of ARGV (whose length is ARGC) for option characters
rlm@1 465 given in OPTSTRING.
rlm@1 466
rlm@1 467 If an element of ARGV starts with '-', and is not exactly "-" or "--",
rlm@1 468 then it is an option element. The characters of this element
rlm@1 469 (aside from the initial '-') are option characters. If `getopt'
rlm@1 470 is called repeatedly, it returns successively each of the option characters
rlm@1 471 from each of the option elements.
rlm@1 472
rlm@1 473 If `getopt' finds another option character, it returns that character,
rlm@1 474 updating `optind' and `nextchar' so that the next call to `getopt' can
rlm@1 475 resume the scan with the following option character or ARGV-element.
rlm@1 476
rlm@1 477 If there are no more option characters, `getopt' returns -1.
rlm@1 478 Then `optind' is the index in ARGV of the first ARGV-element
rlm@1 479 that is not an option. (The ARGV-elements have been permuted
rlm@1 480 so that those that are not options now come last.)
rlm@1 481
rlm@1 482 OPTSTRING is a string containing the legitimate option characters.
rlm@1 483 If an option character is seen that is not listed in OPTSTRING,
rlm@1 484 return '?' after printing an error message. If you set `opterr' to
rlm@1 485 zero, the error message is suppressed but we still return '?'.
rlm@1 486
rlm@1 487 If a char in OPTSTRING is followed by a colon, that means it wants an arg,
rlm@1 488 so the following text in the same ARGV-element, or the text of the following
rlm@1 489 ARGV-element, is returned in `optarg'. Two colons mean an option that
rlm@1 490 wants an optional arg; if there is text in the current ARGV-element,
rlm@1 491 it is returned in `optarg', otherwise `optarg' is set to zero.
rlm@1 492
rlm@1 493 If OPTSTRING starts with `-' or `+', it requests different methods of
rlm@1 494 handling the non-option ARGV-elements.
rlm@1 495 See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
rlm@1 496
rlm@1 497 Long-named options begin with `--' instead of `-'.
rlm@1 498 Their names may be abbreviated as long as the abbreviation is unique
rlm@1 499 or is an exact match for some defined option. If they have an
rlm@1 500 argument, it follows the option name in the same ARGV-element, separated
rlm@1 501 from the option name by a `=', or else the in next ARGV-element.
rlm@1 502 When `getopt' finds a long-named option, it returns 0 if that option's
rlm@1 503 `flag' field is nonzero, the value of the option's `val' field
rlm@1 504 if the `flag' field is zero.
rlm@1 505
rlm@1 506 The elements of ARGV aren't really const, because we permute them.
rlm@1 507 But we pretend they're const in the prototype to be compatible
rlm@1 508 with other systems.
rlm@1 509
rlm@1 510 LONGOPTS is a vector of `struct option' terminated by an
rlm@1 511 element containing a name which is zero.
rlm@1 512
rlm@1 513 LONGIND returns the index in LONGOPT of the long-named option found.
rlm@1 514 It is only valid when a long-named option has been found by the most
rlm@1 515 recent call.
rlm@1 516
rlm@1 517 If LONG_ONLY is nonzero, '-' as well as '--' can introduce
rlm@1 518 long-named options. */
rlm@1 519
rlm@1 520 int
rlm@1 521 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
rlm@1 522 int argc;
rlm@1 523 char *const *argv;
rlm@1 524 const char *optstring;
rlm@1 525 const struct option *longopts;
rlm@1 526 int *longind;
rlm@1 527 int long_only;
rlm@1 528 {
rlm@1 529 optarg = NULL;
rlm@1 530
rlm@1 531 if (optind == 0 || !__getopt_initialized)
rlm@1 532 {
rlm@1 533 if (optind == 0)
rlm@1 534 optind = 1; /* Don't scan ARGV[0], the program name. */
rlm@1 535 optstring = _getopt_initialize (argc, argv, optstring);
rlm@1 536 __getopt_initialized = 1;
rlm@1 537 }
rlm@1 538
rlm@1 539 /* Test whether ARGV[optind] points to a non-option argument.
rlm@1 540 Either it does not have option syntax, or there is an environment flag
rlm@1 541 from the shell indicating it is not an option. The later information
rlm@1 542 is only used when the used in the GNU libc. */
rlm@1 543 #ifdef _LIBC
rlm@1 544 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
rlm@1 545 || (optind < nonoption_flags_len \
rlm@1 546 && __getopt_nonoption_flags[optind] == '1'))
rlm@1 547 #else
rlm@1 548 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
rlm@1 549 #endif
rlm@1 550
rlm@1 551 if (nextchar == NULL || *nextchar == '\0')
rlm@1 552 {
rlm@1 553 /* Advance to the next ARGV-element. */
rlm@1 554
rlm@1 555 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
rlm@1 556 moved back by the user (who may also have changed the arguments). */
rlm@1 557 if (last_nonopt > optind)
rlm@1 558 last_nonopt = optind;
rlm@1 559 if (first_nonopt > optind)
rlm@1 560 first_nonopt = optind;
rlm@1 561
rlm@1 562 if (ordering == PERMUTE)
rlm@1 563 {
rlm@1 564 /* If we have just processed some options following some non-options,
rlm@1 565 exchange them so that the options come first. */
rlm@1 566
rlm@1 567 if (first_nonopt != last_nonopt && last_nonopt != optind)
rlm@1 568 exchange ((char **) argv);
rlm@1 569 else if (last_nonopt != optind)
rlm@1 570 first_nonopt = optind;
rlm@1 571
rlm@1 572 /* Skip any additional non-options
rlm@1 573 and extend the range of non-options previously skipped. */
rlm@1 574
rlm@1 575 while (optind < argc && NONOPTION_P)
rlm@1 576 optind++;
rlm@1 577 last_nonopt = optind;
rlm@1 578 }
rlm@1 579
rlm@1 580 /* The special ARGV-element `--' means premature end of options.
rlm@1 581 Skip it like a null option,
rlm@1 582 then exchange with previous non-options as if it were an option,
rlm@1 583 then skip everything else like a non-option. */
rlm@1 584
rlm@1 585 if (optind != argc && !strcmp (argv[optind], "--"))
rlm@1 586 {
rlm@1 587 optind++;
rlm@1 588
rlm@1 589 if (first_nonopt != last_nonopt && last_nonopt != optind)
rlm@1 590 exchange ((char **) argv);
rlm@1 591 else if (first_nonopt == last_nonopt)
rlm@1 592 first_nonopt = optind;
rlm@1 593 last_nonopt = argc;
rlm@1 594
rlm@1 595 optind = argc;
rlm@1 596 }
rlm@1 597
rlm@1 598 /* If we have done all the ARGV-elements, stop the scan
rlm@1 599 and back over any non-options that we skipped and permuted. */
rlm@1 600
rlm@1 601 if (optind == argc)
rlm@1 602 {
rlm@1 603 /* Set the next-arg-index to point at the non-options
rlm@1 604 that we previously skipped, so the caller will digest them. */
rlm@1 605 if (first_nonopt != last_nonopt)
rlm@1 606 optind = first_nonopt;
rlm@1 607 return -1;
rlm@1 608 }
rlm@1 609
rlm@1 610 /* If we have come to a non-option and did not permute it,
rlm@1 611 either stop the scan or describe it to the caller and pass it by. */
rlm@1 612
rlm@1 613 if (NONOPTION_P)
rlm@1 614 {
rlm@1 615 if (ordering == REQUIRE_ORDER)
rlm@1 616 return -1;
rlm@1 617 optarg = argv[optind++];
rlm@1 618 return 1;
rlm@1 619 }
rlm@1 620
rlm@1 621 /* We have found another option-ARGV-element.
rlm@1 622 Skip the initial punctuation. */
rlm@1 623
rlm@1 624 nextchar = (argv[optind] + 1
rlm@1 625 + (longopts != NULL && argv[optind][1] == '-'));
rlm@1 626 }
rlm@1 627
rlm@1 628 /* Decode the current option-ARGV-element. */
rlm@1 629
rlm@1 630 /* Check whether the ARGV-element is a long option.
rlm@1 631
rlm@1 632 If long_only and the ARGV-element has the form "-f", where f is
rlm@1 633 a valid short option, don't consider it an abbreviated form of
rlm@1 634 a long option that starts with f. Otherwise there would be no
rlm@1 635 way to give the -f short option.
rlm@1 636
rlm@1 637 On the other hand, if there's a long option "fubar" and
rlm@1 638 the ARGV-element is "-fu", do consider that an abbreviation of
rlm@1 639 the long option, just like "--fu", and not "-f" with arg "u".
rlm@1 640
rlm@1 641 This distinction seems to be the most useful approach. */
rlm@1 642
rlm@1 643 if (longopts != NULL
rlm@1 644 && (argv[optind][1] == '-'
rlm@1 645 || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
rlm@1 646 {
rlm@1 647 char *nameend;
rlm@1 648 const struct option *p;
rlm@1 649 const struct option *pfound = NULL;
rlm@1 650 int exact = 0;
rlm@1 651 int ambig = 0;
rlm@1 652 int indfound = -1;
rlm@1 653 int option_index;
rlm@1 654
rlm@1 655 for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
rlm@1 656 /* Do nothing. */ ;
rlm@1 657
rlm@1 658 /* Test all long options for either exact match
rlm@1 659 or abbreviated matches. */
rlm@1 660 for (p = longopts, option_index = 0; p->name; p++, option_index++)
rlm@1 661 if (!strncmp (p->name, nextchar, nameend - nextchar))
rlm@1 662 {
rlm@1 663 if ((unsigned int) (nameend - nextchar)
rlm@1 664 == (unsigned int) strlen (p->name))
rlm@1 665 {
rlm@1 666 /* Exact match found. */
rlm@1 667 pfound = p;
rlm@1 668 indfound = option_index;
rlm@1 669 exact = 1;
rlm@1 670 break;
rlm@1 671 }
rlm@1 672 else if (pfound == NULL)
rlm@1 673 {
rlm@1 674 /* First nonexact match found. */
rlm@1 675 pfound = p;
rlm@1 676 indfound = option_index;
rlm@1 677 }
rlm@1 678 else
rlm@1 679 /* Second or later nonexact match found. */
rlm@1 680 ambig = 1;
rlm@1 681 }
rlm@1 682
rlm@1 683 if (ambig && !exact)
rlm@1 684 {
rlm@1 685 if (opterr)
rlm@1 686 fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
rlm@1 687 argv[0], argv[optind]);
rlm@1 688 nextchar += strlen (nextchar);
rlm@1 689 optind++;
rlm@1 690 optopt = 0;
rlm@1 691 return '?';
rlm@1 692 }
rlm@1 693
rlm@1 694 if (pfound != NULL)
rlm@1 695 {
rlm@1 696 option_index = indfound;
rlm@1 697 optind++;
rlm@1 698 if (*nameend)
rlm@1 699 {
rlm@1 700 /* Don't test has_arg with >, because some C compilers don't
rlm@1 701 allow it to be used on enums. */
rlm@1 702 if (pfound->has_arg)
rlm@1 703 optarg = nameend + 1;
rlm@1 704 else
rlm@1 705 {
rlm@1 706 if (opterr)
rlm@1 707 {
rlm@1 708 if (argv[optind - 1][1] == '-')
rlm@1 709 /* --option */
rlm@1 710 fprintf (stderr,
rlm@1 711 _("%s: option `--%s' doesn't allow an argument\n"),
rlm@1 712 argv[0], pfound->name);
rlm@1 713 else
rlm@1 714 /* +option or -option */
rlm@1 715 fprintf (stderr,
rlm@1 716 _("%s: option `%c%s' doesn't allow an argument\n"),
rlm@1 717 argv[0], argv[optind - 1][0], pfound->name);
rlm@1 718
rlm@1 719 nextchar += strlen (nextchar);
rlm@1 720
rlm@1 721 optopt = pfound->val;
rlm@1 722 return '?';
rlm@1 723 }
rlm@1 724 }
rlm@1 725 }
rlm@1 726 else if (pfound->has_arg == 1)
rlm@1 727 {
rlm@1 728 if (optind < argc)
rlm@1 729 optarg = argv[optind++];
rlm@1 730 else
rlm@1 731 {
rlm@1 732 if (opterr)
rlm@1 733 fprintf (stderr,
rlm@1 734 _("%s: option `%s' requires an argument\n"),
rlm@1 735 argv[0], argv[optind - 1]);
rlm@1 736 nextchar += strlen (nextchar);
rlm@1 737 optopt = pfound->val;
rlm@1 738 return optstring[0] == ':' ? ':' : '?';
rlm@1 739 }
rlm@1 740 }
rlm@1 741 nextchar += strlen (nextchar);
rlm@1 742 if (longind != NULL)
rlm@1 743 *longind = option_index;
rlm@1 744 if (pfound->flag)
rlm@1 745 {
rlm@1 746 *(pfound->flag) = pfound->val;
rlm@1 747 return 0;
rlm@1 748 }
rlm@1 749 return pfound->val;
rlm@1 750 }
rlm@1 751
rlm@1 752 /* Can't find it as a long option. If this is not getopt_long_only,
rlm@1 753 or the option starts with '--' or is not a valid short
rlm@1 754 option, then it's an error.
rlm@1 755 Otherwise interpret it as a short option. */
rlm@1 756 if (!long_only || argv[optind][1] == '-'
rlm@1 757 || my_index (optstring, *nextchar) == NULL)
rlm@1 758 {
rlm@1 759 if (opterr)
rlm@1 760 {
rlm@1 761 if (argv[optind][1] == '-')
rlm@1 762 /* --option */
rlm@1 763 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
rlm@1 764 argv[0], nextchar);
rlm@1 765 else
rlm@1 766 /* +option or -option */
rlm@1 767 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
rlm@1 768 argv[0], argv[optind][0], nextchar);
rlm@1 769 }
rlm@1 770 nextchar = (char *) "";
rlm@1 771 optind++;
rlm@1 772 optopt = 0;
rlm@1 773 return '?';
rlm@1 774 }
rlm@1 775 }
rlm@1 776
rlm@1 777 /* Look at and handle the next short option-character. */
rlm@1 778
rlm@1 779 {
rlm@1 780 char c = *nextchar++;
rlm@1 781 char *temp = my_index (optstring, c);
rlm@1 782
rlm@1 783 /* Increment `optind' when we start to process its last character. */
rlm@1 784 if (*nextchar == '\0')
rlm@1 785 ++optind;
rlm@1 786
rlm@1 787 if (temp == NULL || c == ':')
rlm@1 788 {
rlm@1 789 if (opterr)
rlm@1 790 {
rlm@1 791 if (posixly_correct)
rlm@1 792 /* 1003.2 specifies the format of this message. */
rlm@1 793 fprintf (stderr, _("%s: illegal option -- %c\n"),
rlm@1 794 argv[0], c);
rlm@1 795 else
rlm@1 796 fprintf (stderr, _("%s: invalid option -- %c\n"),
rlm@1 797 argv[0], c);
rlm@1 798 }
rlm@1 799 optopt = c;
rlm@1 800 return '?';
rlm@1 801 }
rlm@1 802 /* Convenience. Treat POSIX -W foo same as long option --foo */
rlm@1 803 if (temp[0] == 'W' && temp[1] == ';')
rlm@1 804 {
rlm@1 805 char *nameend;
rlm@1 806 const struct option *p;
rlm@1 807 const struct option *pfound = NULL;
rlm@1 808 int exact = 0;
rlm@1 809 int ambig = 0;
rlm@1 810 int indfound = 0;
rlm@1 811 int option_index;
rlm@1 812
rlm@1 813 /* This is an option that requires an argument. */
rlm@1 814 if (*nextchar != '\0')
rlm@1 815 {
rlm@1 816 optarg = nextchar;
rlm@1 817 /* If we end this ARGV-element by taking the rest as an arg,
rlm@1 818 we must advance to the next element now. */
rlm@1 819 optind++;
rlm@1 820 }
rlm@1 821 else if (optind == argc)
rlm@1 822 {
rlm@1 823 if (opterr)
rlm@1 824 {
rlm@1 825 /* 1003.2 specifies the format of this message. */
rlm@1 826 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
rlm@1 827 argv[0], c);
rlm@1 828 }
rlm@1 829 optopt = c;
rlm@1 830 if (optstring[0] == ':')
rlm@1 831 c = ':';
rlm@1 832 else
rlm@1 833 c = '?';
rlm@1 834 return c;
rlm@1 835 }
rlm@1 836 else
rlm@1 837 /* We already incremented `optind' once;
rlm@1 838 increment it again when taking next ARGV-elt as argument. */
rlm@1 839 optarg = argv[optind++];
rlm@1 840
rlm@1 841 /* optarg is now the argument, see if it's in the
rlm@1 842 table of longopts. */
rlm@1 843
rlm@1 844 for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
rlm@1 845 /* Do nothing. */ ;
rlm@1 846
rlm@1 847 /* Test all long options for either exact match
rlm@1 848 or abbreviated matches. */
rlm@1 849 for (p = longopts, option_index = 0; p->name; p++, option_index++)
rlm@1 850 if (!strncmp (p->name, nextchar, nameend - nextchar))
rlm@1 851 {
rlm@1 852 if ((unsigned int) (nameend - nextchar) == strlen (p->name))
rlm@1 853 {
rlm@1 854 /* Exact match found. */
rlm@1 855 pfound = p;
rlm@1 856 indfound = option_index;
rlm@1 857 exact = 1;
rlm@1 858 break;
rlm@1 859 }
rlm@1 860 else if (pfound == NULL)
rlm@1 861 {
rlm@1 862 /* First nonexact match found. */
rlm@1 863 pfound = p;
rlm@1 864 indfound = option_index;
rlm@1 865 }
rlm@1 866 else
rlm@1 867 /* Second or later nonexact match found. */
rlm@1 868 ambig = 1;
rlm@1 869 }
rlm@1 870 if (ambig && !exact)
rlm@1 871 {
rlm@1 872 if (opterr)
rlm@1 873 fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
rlm@1 874 argv[0], argv[optind]);
rlm@1 875 nextchar += strlen (nextchar);
rlm@1 876 optind++;
rlm@1 877 return '?';
rlm@1 878 }
rlm@1 879 if (pfound != NULL)
rlm@1 880 {
rlm@1 881 option_index = indfound;
rlm@1 882 if (*nameend)
rlm@1 883 {
rlm@1 884 /* Don't test has_arg with >, because some C compilers don't
rlm@1 885 allow it to be used on enums. */
rlm@1 886 if (pfound->has_arg)
rlm@1 887 optarg = nameend + 1;
rlm@1 888 else
rlm@1 889 {
rlm@1 890 if (opterr)
rlm@1 891 fprintf (stderr, _("\
rlm@1 892 %s: option `-W %s' doesn't allow an argument\n"),
rlm@1 893 argv[0], pfound->name);
rlm@1 894
rlm@1 895 nextchar += strlen (nextchar);
rlm@1 896 return '?';
rlm@1 897 }
rlm@1 898 }
rlm@1 899 else if (pfound->has_arg == 1)
rlm@1 900 {
rlm@1 901 if (optind < argc)
rlm@1 902 optarg = argv[optind++];
rlm@1 903 else
rlm@1 904 {
rlm@1 905 if (opterr)
rlm@1 906 fprintf (stderr,
rlm@1 907 _("%s: option `%s' requires an argument\n"),
rlm@1 908 argv[0], argv[optind - 1]);
rlm@1 909 nextchar += strlen (nextchar);
rlm@1 910 return optstring[0] == ':' ? ':' : '?';
rlm@1 911 }
rlm@1 912 }
rlm@1 913 nextchar += strlen (nextchar);
rlm@1 914 if (longind != NULL)
rlm@1 915 *longind = option_index;
rlm@1 916 if (pfound->flag)
rlm@1 917 {
rlm@1 918 *(pfound->flag) = pfound->val;
rlm@1 919 return 0;
rlm@1 920 }
rlm@1 921 return pfound->val;
rlm@1 922 }
rlm@1 923 nextchar = NULL;
rlm@1 924 return 'W'; /* Let the application handle it. */
rlm@1 925 }
rlm@1 926 if (temp[1] == ':')
rlm@1 927 {
rlm@1 928 if (temp[2] == ':')
rlm@1 929 {
rlm@1 930 /* This is an option that accepts an argument optionally. */
rlm@1 931 if (*nextchar != '\0')
rlm@1 932 {
rlm@1 933 optarg = nextchar;
rlm@1 934 optind++;
rlm@1 935 }
rlm@1 936 else
rlm@1 937 optarg = NULL;
rlm@1 938 nextchar = NULL;
rlm@1 939 }
rlm@1 940 else
rlm@1 941 {
rlm@1 942 /* This is an option that requires an argument. */
rlm@1 943 if (*nextchar != '\0')
rlm@1 944 {
rlm@1 945 optarg = nextchar;
rlm@1 946 /* If we end this ARGV-element by taking the rest as an arg,
rlm@1 947 we must advance to the next element now. */
rlm@1 948 optind++;
rlm@1 949 }
rlm@1 950 else if (optind == argc)
rlm@1 951 {
rlm@1 952 if (opterr)
rlm@1 953 {
rlm@1 954 /* 1003.2 specifies the format of this message. */
rlm@1 955 fprintf (stderr,
rlm@1 956 _("%s: option requires an argument -- %c\n"),
rlm@1 957 argv[0], c);
rlm@1 958 }
rlm@1 959 optopt = c;
rlm@1 960 if (optstring[0] == ':')
rlm@1 961 c = ':';
rlm@1 962 else
rlm@1 963 c = '?';
rlm@1 964 }
rlm@1 965 else
rlm@1 966 /* We already incremented `optind' once;
rlm@1 967 increment it again when taking next ARGV-elt as argument. */
rlm@1 968 optarg = argv[optind++];
rlm@1 969 nextchar = NULL;
rlm@1 970 }
rlm@1 971 }
rlm@1 972 return c;
rlm@1 973 }
rlm@1 974 }
rlm@1 975
rlm@1 976 int
rlm@1 977 getopt (argc, argv, optstring)
rlm@1 978 int argc;
rlm@1 979 char *const *argv;
rlm@1 980 const char *optstring;
rlm@1 981 {
rlm@1 982 return _getopt_internal (argc, argv, optstring,
rlm@1 983 (const struct option *) 0,
rlm@1 984 (int *) 0,
rlm@1 985 0);
rlm@1 986 }
rlm@1 987
rlm@1 988 #endif /* Not ELIDE_CODE. */
rlm@1 989
rlm@1 990 #ifdef TEST
rlm@1 991
rlm@1 992 /* Compile with -DTEST to make an executable for use in testing
rlm@1 993 the above definition of `getopt'. */
rlm@1 994
rlm@1 995 int
rlm@1 996 main (argc, argv)
rlm@1 997 int argc;
rlm@1 998 char **argv;
rlm@1 999 {
rlm@1 1000 int c;
rlm@1 1001 int digit_optind = 0;
rlm@1 1002
rlm@1 1003 while (1)
rlm@1 1004 {
rlm@1 1005 int this_option_optind = optind ? optind : 1;
rlm@1 1006
rlm@1 1007 c = getopt (argc, argv, "abc:d:0123456789");
rlm@1 1008 if (c == -1)
rlm@1 1009 break;
rlm@1 1010
rlm@1 1011 switch (c)
rlm@1 1012 {
rlm@1 1013 case '0':
rlm@1 1014 case '1':
rlm@1 1015 case '2':
rlm@1 1016 case '3':
rlm@1 1017 case '4':
rlm@1 1018 case '5':
rlm@1 1019 case '6':
rlm@1 1020 case '7':
rlm@1 1021 case '8':
rlm@1 1022 case '9':
rlm@1 1023 if (digit_optind != 0 && digit_optind != this_option_optind)
rlm@1 1024 printf ("digits occur in two different argv-elements.\n");
rlm@1 1025 digit_optind = this_option_optind;
rlm@1 1026 printf ("option %c\n", c);
rlm@1 1027 break;
rlm@1 1028
rlm@1 1029 case 'a':
rlm@1 1030 printf ("option a\n");
rlm@1 1031 break;
rlm@1 1032
rlm@1 1033 case 'b':
rlm@1 1034 printf ("option b\n");
rlm@1 1035 break;
rlm@1 1036
rlm@1 1037 case 'c':
rlm@1 1038 printf ("option c with value `%s'\n", optarg);
rlm@1 1039 break;
rlm@1 1040
rlm@1 1041 case '?':
rlm@1 1042 break;
rlm@1 1043
rlm@1 1044 default:
rlm@1 1045 printf ("?? getopt returned character code 0%o ??\n", c);
rlm@1 1046 }
rlm@1 1047 }
rlm@1 1048
rlm@1 1049 if (optind < argc)
rlm@1 1050 {
rlm@1 1051 printf ("non-option ARGV-elements: ");
rlm@1 1052 while (optind < argc)
rlm@1 1053 printf ("%s ", argv[optind++]);
rlm@1 1054 printf ("\n");
rlm@1 1055 }
rlm@1 1056
rlm@1 1057 exit (0);
rlm@1 1058 }
rlm@1 1059
rlm@1 1060 #endif /* TEST */