00001 /* Getopt for GNU. 00002 NOTE: getopt is now part of the C library, so if you don't know what 00003 "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu 00004 before changing it! 00005 00006 Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95 00007 Free Software Foundation, Inc. 00008 00009 This program is free software; you can redistribute it and/or modify it 00010 under the terms of the GNU General Public License as published by the 00011 Free Software Foundation; either version 2, or (at your option) any 00012 later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 00022 00023 /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. 00024 Ditto for AIX 3.2 and <stdlib.h>. */ 00025 #ifndef _NO_PROTO 00026 #define _NO_PROTO 00027 #endif 00028 00029 #ifdef HAVE_CONFIG_H 00030 #include "config.h" 00031 #endif 00032 00033 #if !defined (__STDC__) || !__STDC__ 00034 /* This is a separate conditional since some stdc systems 00035 reject `defined (const)'. */ 00036 #ifndef const 00037 #define const 00038 #endif 00039 #endif 00040 00041 #include <stdio.h> 00042 #include <string.h> 00043 00044 /* Comment out all this code if we are using the GNU C Library, and are not 00045 actually compiling the library itself. This code is part of the GNU C 00046 Library, but also included in many other GNU distributions. Compiling 00047 and linking in this code is a waste when using the GNU C library 00048 (especially if it is a shared library). Rather than having every GNU 00049 program understand `configure --with-gnu-libc' and omit the object files, 00050 it is simpler to just do this in the source for each such file. */ 00051 00052 #if defined (_LIBC) || !defined (__GNU_LIBRARY__) 00053 00054 00055 /* This needs to come after some library #include 00056 to get __GNU_LIBRARY__ defined. */ 00057 #ifdef __GNU_LIBRARY__ 00058 /* Don't include stdlib.h for non-GNU C libraries because some of them 00059 contain conflicting prototypes for getopt. */ 00060 #include <stdlib.h> 00061 #endif /* GNU C library. */ 00062 00063 /* This is for other GNU distributions with internationalized messages. 00064 The GNU C Library itself does not yet support such messages. */ 00065 #if HAVE_LIBINTL_H 00066 # include <libintl.h> 00067 #else 00068 # define gettext(msgid) (msgid) 00069 #endif 00070 00071 /* This version of `getopt' appears to the caller like standard Unix `getopt' 00072 but it behaves differently for the user, since it allows the user 00073 to intersperse the options with the other arguments. 00074 00075 As `getopt' works, it permutes the elements of ARGV so that, 00076 when it is done, all the options precede everything else. Thus 00077 all application programs are extended to handle flexible argument order. 00078 00079 Setting the environment variable POSIXLY_CORRECT disables permutation. 00080 Then the behavior is completely standard. 00081 00082 GNU application programs can use a third alternative mode in which 00083 they can distinguish the relative order of options and other arguments. */ 00084 00085 #include "getopt.h" 00086 00087 /* For communication from `getopt' to the caller. 00088 When `getopt' finds an option that takes an argument, 00089 the argument value is returned here. 00090 Also, when `ordering' is RETURN_IN_ORDER, 00091 each non-option ARGV-element is returned here. */ 00092 00093 char *optarg = NULL; 00094 00095 /* Index in ARGV of the next element to be scanned. 00096 This is used for communication to and from the caller 00097 and for communication between successive calls to `getopt'. 00098 00099 On entry to `getopt', zero means this is the first call; initialize. 00100 00101 When `getopt' returns EOF, this is the index of the first of the 00102 non-option elements that the caller should itself scan. 00103 00104 Otherwise, `optind' communicates from one call to the next 00105 how much of ARGV has been scanned so far. */ 00106 00107 /* XXX 1003.2 says this must be 1 before any call. */ 00108 int optind = 0; 00109 00110 /* The next char to be scanned in the option-element 00111 in which the last option character we returned was found. 00112 This allows us to pick up the scan where we left off. 00113 00114 If this is zero, or a null string, it means resume the scan 00115 by advancing to the next ARGV-element. */ 00116 00117 static char *nextchar; 00118 00119 /* Callers store zero here to inhibit the error message 00120 for unrecognized options. */ 00121 00122 int opterr = 1; 00123 00124 /* Set to an option character which was unrecognized. 00125 This must be initialized on some systems to avoid linking in the 00126 system's own getopt implementation. */ 00127 00128 int optopt = '?'; 00129 00130 /* Describe how to deal with options that follow non-option ARGV-elements. 00131 00132 If the caller did not specify anything, 00133 the default is REQUIRE_ORDER if the environment variable 00134 POSIXLY_CORRECT is defined, PERMUTE otherwise. 00135 00136 REQUIRE_ORDER means don't recognize them as options; 00137 stop option processing when the first non-option is seen. 00138 This is what Unix does. 00139 This mode of operation is selected by either setting the environment 00140 variable POSIXLY_CORRECT, or using `+' as the first character 00141 of the list of option characters. 00142 00143 PERMUTE is the default. We permute the contents of ARGV as we scan, 00144 so that eventually all the non-options are at the end. This allows options 00145 to be given in any order, even with programs that were not written to 00146 expect this. 00147 00148 RETURN_IN_ORDER is an option available to programs that were written 00149 to expect options and other ARGV-elements in any order and that care about 00150 the ordering of the two. We describe each non-option ARGV-element 00151 as if it were the argument of an option with character code 1. 00152 Using `-' as the first character of the list of option characters 00153 selects this mode of operation. 00154 00155 The special argument `--' forces an end of option-scanning regardless 00156 of the value of `ordering'. In the case of RETURN_IN_ORDER, only 00157 `--' can cause `getopt' to return EOF with `optind' != ARGC. */ 00158 00159 static enum 00160 { 00161 REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER 00162 } ordering; 00163 00164 /* Value of POSIXLY_CORRECT environment variable. */ 00165 static char *posixly_correct; 00166 00167 #ifdef __GNU_LIBRARY__ 00168 /* We want to avoid inclusion of string.h with non-GNU libraries 00169 because there are many ways it can cause trouble. 00170 On some systems, it contains special magic macros that don't work 00171 in GCC. */ 00172 #include <string.h> 00173 #define my_index strchr 00174 #else 00175 00176 /* Avoid depending on library functions or files 00177 whose names are inconsistent. */ 00178 00179 char *getenv (); 00180 00181 static char * 00182 my_index (str, chr) 00183 const char *str; 00184 int chr; 00185 { 00186 while (*str) 00187 { 00188 if (*str == chr) 00189 return (char *) str; 00190 str++; 00191 } 00192 return 0; 00193 } 00194 00195 /* If using GCC, we can safely declare strlen this way. 00196 If not using GCC, it is ok not to declare it. */ 00197 #ifdef __GNUC__ 00198 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. 00199 That was relevant to code that was here before. */ 00200 #if !defined (__STDC__) || !__STDC__ 00201 /* gcc with -traditional declares the built-in strlen to return int, 00202 and has done so at least since version 2.4.5. -- rms. */ 00203 extern int strlen (const char *); 00204 #endif /* not __STDC__ */ 00205 #endif /* __GNUC__ */ 00206 00207 #endif /* not __GNU_LIBRARY__ */ 00208 00209 /* Handle permutation of arguments. */ 00210 00211 /* Describe the part of ARGV that contains non-options that have 00212 been skipped. `first_nonopt' is the index in ARGV of the first of them; 00213 `last_nonopt' is the index after the last of them. */ 00214 00215 static int first_nonopt; 00216 static int last_nonopt; 00217 00218 /* Exchange two adjacent subsequences of ARGV. 00219 One subsequence is elements [first_nonopt,last_nonopt) 00220 which contains all the non-options that have been skipped so far. 00221 The other is elements [last_nonopt,optind), which contains all 00222 the options processed since those non-options were skipped. 00223 00224 `first_nonopt' and `last_nonopt' are relocated so that they describe 00225 the new indices of the non-options in ARGV after they are moved. */ 00226 00227 static void 00228 exchange (argv) 00229 char **argv; 00230 { 00231 int bottom = first_nonopt; 00232 int middle = last_nonopt; 00233 int top = optind; 00234 char *tem; 00235 00236 /* Exchange the shorter segment with the far end of the longer segment. 00237 That puts the shorter segment into the right place. 00238 It leaves the longer segment in the right place overall, 00239 but it consists of two parts that need to be swapped next. */ 00240 00241 while (top > middle && middle > bottom) 00242 { 00243 if (top - middle > middle - bottom) 00244 { 00245 /* Bottom segment is the short one. */ 00246 int len = middle - bottom; 00247 register int i; 00248 00249 /* Swap it with the top part of the top segment. */ 00250 for (i = 0; i < len; i++) 00251 { 00252 tem = argv[bottom + i]; 00253 argv[bottom + i] = argv[top - (middle - bottom) + i]; 00254 argv[top - (middle - bottom) + i] = tem; 00255 } 00256 /* Exclude the moved bottom segment from further swapping. */ 00257 top -= len; 00258 } 00259 else 00260 { 00261 /* Top segment is the short one. */ 00262 int len = top - middle; 00263 register int i; 00264 00265 /* Swap it with the bottom part of the bottom segment. */ 00266 for (i = 0; i < len; i++) 00267 { 00268 tem = argv[bottom + i]; 00269 argv[bottom + i] = argv[middle + i]; 00270 argv[middle + i] = tem; 00271 } 00272 /* Exclude the moved top segment from further swapping. */ 00273 bottom += len; 00274 } 00275 } 00276 00277 /* Update records for the slots the non-options now occupy. */ 00278 00279 first_nonopt += (optind - last_nonopt); 00280 last_nonopt = optind; 00281 } 00282 00283 /* Initialize the internal data when the first call is made. */ 00284 00285 static const char * 00286 _getopt_initialize (optstring) 00287 const char *optstring; 00288 { 00289 /* Start processing options with ARGV-element 1 (since ARGV-element 0 00290 is the program name); the sequence of previously skipped 00291 non-option ARGV-elements is empty. */ 00292 00293 first_nonopt = last_nonopt = optind = 1; 00294 00295 nextchar = NULL; 00296 00297 posixly_correct = getenv ("POSIXLY_CORRECT"); 00298 00299 /* Determine how to handle the ordering of options and nonoptions. */ 00300 00301 if (optstring[0] == '-') 00302 { 00303 ordering = RETURN_IN_ORDER; 00304 ++optstring; 00305 } 00306 else if (optstring[0] == '+') 00307 { 00308 ordering = REQUIRE_ORDER; 00309 ++optstring; 00310 } 00311 else if (posixly_correct != NULL) 00312 ordering = REQUIRE_ORDER; 00313 else 00314 ordering = PERMUTE; 00315 00316 return optstring; 00317 } 00318 00319 /* Scan elements of ARGV (whose length is ARGC) for option characters 00320 given in OPTSTRING. 00321 00322 If an element of ARGV starts with '-', and is not exactly "-" or "--", 00323 then it is an option element. The characters of this element 00324 (aside from the initial '-') are option characters. If `getopt' 00325 is called repeatedly, it returns successively each of the option characters 00326 from each of the option elements. 00327 00328 If `getopt' finds another option character, it returns that character, 00329 updating `optind' and `nextchar' so that the next call to `getopt' can 00330 resume the scan with the following option character or ARGV-element. 00331 00332 If there are no more option characters, `getopt' returns `EOF'. 00333 Then `optind' is the index in ARGV of the first ARGV-element 00334 that is not an option. (The ARGV-elements have been permuted 00335 so that those that are not options now come last.) 00336 00337 OPTSTRING is a string containing the legitimate option characters. 00338 If an option character is seen that is not listed in OPTSTRING, 00339 return '?' after printing an error message. If you set `opterr' to 00340 zero, the error message is suppressed but we still return '?'. 00341 00342 If a char in OPTSTRING is followed by a colon, that means it wants an arg, 00343 so the following text in the same ARGV-element, or the text of the following 00344 ARGV-element, is returned in `optarg'. Two colons mean an option that 00345 wants an optional arg; if there is text in the current ARGV-element, 00346 it is returned in `optarg', otherwise `optarg' is set to zero. 00347 00348 If OPTSTRING starts with `-' or `+', it requests different methods of 00349 handling the non-option ARGV-elements. 00350 See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. 00351 00352 Long-named options begin with `--' instead of `-'. 00353 Their names may be abbreviated as long as the abbreviation is unique 00354 or is an exact match for some defined option. If they have an 00355 argument, it follows the option name in the same ARGV-element, separated 00356 from the option name by a `=', or else the in next ARGV-element. 00357 When `getopt' finds a long-named option, it returns 0 if that option's 00358 `flag' field is nonzero, the value of the option's `val' field 00359 if the `flag' field is zero. 00360 00361 The elements of ARGV aren't really const, because we permute them. 00362 But we pretend they're const in the prototype to be compatible 00363 with other systems. 00364 00365 LONGOPTS is a vector of `struct option' terminated by an 00366 element containing a name which is zero. 00367 00368 LONGIND returns the index in LONGOPT of the long-named option found. 00369 It is only valid when a long-named option has been found by the most 00370 recent call. 00371 00372 If LONG_ONLY is nonzero, '-' as well as '--' can introduce 00373 long-named options. */ 00374 00375 int 00376 _getopt_internal (argc, argv, optstring, longopts, longind, long_only) 00377 int argc; 00378 char *const *argv; 00379 const char *optstring; 00380 const struct option *longopts; 00381 int *longind; 00382 int long_only; 00383 { 00384 optarg = NULL; 00385 00386 if (optind == 0) 00387 { 00388 optstring = _getopt_initialize (optstring); 00389 optind = 1; /* Don't scan ARGV[0], the program name. */ 00390 } 00391 00392 if (nextchar == NULL || *nextchar == '\0') 00393 { 00394 /* Advance to the next ARGV-element. */ 00395 00396 if (ordering == PERMUTE) 00397 { 00398 /* If we have just processed some options following some non-options, 00399 exchange them so that the options come first. */ 00400 00401 if (first_nonopt != last_nonopt && last_nonopt != optind) 00402 exchange ((char **) argv); 00403 else if (last_nonopt != optind) 00404 first_nonopt = optind; 00405 00406 /* Skip any additional non-options 00407 and extend the range of non-options previously skipped. */ 00408 00409 while (optind < argc 00410 && (argv[optind][0] != '-' || argv[optind][1] == '\0')) 00411 optind++; 00412 last_nonopt = optind; 00413 } 00414 00415 /* The special ARGV-element `--' means premature end of options. 00416 Skip it like a null option, 00417 then exchange with previous non-options as if it were an option, 00418 then skip everything else like a non-option. */ 00419 00420 if (optind != argc && !strcmp (argv[optind], "--")) 00421 { 00422 optind++; 00423 00424 if (first_nonopt != last_nonopt && last_nonopt != optind) 00425 exchange ((char **) argv); 00426 else if (first_nonopt == last_nonopt) 00427 first_nonopt = optind; 00428 last_nonopt = argc; 00429 00430 optind = argc; 00431 } 00432 00433 /* If we have done all the ARGV-elements, stop the scan 00434 and back over any non-options that we skipped and permuted. */ 00435 00436 if (optind == argc) 00437 { 00438 /* Set the next-arg-index to point at the non-options 00439 that we previously skipped, so the caller will digest them. */ 00440 if (first_nonopt != last_nonopt) 00441 optind = first_nonopt; 00442 return EOF; 00443 } 00444 00445 /* If we have come to a non-option and did not permute it, 00446 either stop the scan or describe it to the caller and pass it by. */ 00447 00448 if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) 00449 { 00450 if (ordering == REQUIRE_ORDER) 00451 return EOF; 00452 optarg = argv[optind++]; 00453 return 1; 00454 } 00455 00456 /* We have found another option-ARGV-element. 00457 Skip the initial punctuation. */ 00458 00459 nextchar = (argv[optind] + 1 00460 + (longopts != NULL && argv[optind][1] == '-')); 00461 } 00462 00463 /* Decode the current option-ARGV-element. */ 00464 00465 /* Check whether the ARGV-element is a long option. 00466 00467 If long_only and the ARGV-element has the form "-f", where f is 00468 a valid short option, don't consider it an abbreviated form of 00469 a long option that starts with f. Otherwise there would be no 00470 way to give the -f short option. 00471 00472 On the other hand, if there's a long option "fubar" and 00473 the ARGV-element is "-fu", do consider that an abbreviation of 00474 the long option, just like "--fu", and not "-f" with arg "u". 00475 00476 This distinction seems to be the most useful approach. */ 00477 00478 if (longopts != NULL 00479 && (argv[optind][1] == '-' 00480 || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) 00481 { 00482 char *nameend; 00483 const struct option *p; 00484 const struct option *pfound = NULL; 00485 int exact = 0; 00486 int ambig = 0; 00487 int indfound; 00488 int option_index; 00489 00490 for (nameend = nextchar; *nameend && *nameend != '='; nameend++) 00491 /* Do nothing. */ ; 00492 00493 /* Test all long options for either exact match 00494 or abbreviated matches. */ 00495 for (p = longopts, option_index = 0; p->name; p++, option_index++) 00496 if (!strncmp (p->name, nextchar, nameend - nextchar)) 00497 { 00498 if (nameend - nextchar == strlen (p->name)) 00499 { 00500 /* Exact match found. */ 00501 pfound = p; 00502 indfound = option_index; 00503 exact = 1; 00504 break; 00505 } 00506 else if (pfound == NULL) 00507 { 00508 /* First nonexact match found. */ 00509 pfound = p; 00510 indfound = option_index; 00511 } 00512 else 00513 /* Second or later nonexact match found. */ 00514 ambig = 1; 00515 } 00516 00517 if (ambig && !exact) 00518 { 00519 if (opterr) 00520 fprintf (stderr, gettext ("%s: option `%s' is ambiguous\n"), 00521 argv[0], argv[optind]); 00522 nextchar += strlen (nextchar); 00523 optind++; 00524 return '?'; 00525 } 00526 00527 if (pfound != NULL) 00528 { 00529 option_index = indfound; 00530 optind++; 00531 if (*nameend) 00532 { 00533 /* Don't test has_arg with >, because some C compilers don't 00534 allow it to be used on enums. */ 00535 if (pfound->has_arg) 00536 optarg = nameend + 1; 00537 else 00538 { 00539 if (opterr) 00540 if (argv[optind - 1][1] == '-') 00541 /* --option */ 00542 fprintf (stderr, 00543 gettext ("%s: option `--%s' doesn't allow an argument\n"), 00544 argv[0], pfound->name); 00545 else 00546 /* +option or -option */ 00547 fprintf (stderr, 00548 gettext ("%s: option `%c%s' doesn't allow an argument\n"), 00549 argv[0], argv[optind - 1][0], pfound->name); 00550 00551 nextchar += strlen (nextchar); 00552 return '?'; 00553 } 00554 } 00555 else if (pfound->has_arg == 1) 00556 { 00557 if (optind < argc) 00558 optarg = argv[optind++]; 00559 else 00560 { 00561 if (opterr) 00562 fprintf (stderr, 00563 gettext ("%s: option `%s' requires an argument\n"), 00564 argv[0], argv[optind - 1]); 00565 nextchar += strlen (nextchar); 00566 return optstring[0] == ':' ? ':' : '?'; 00567 } 00568 } 00569 nextchar += strlen (nextchar); 00570 if (longind != NULL) 00571 *longind = option_index; 00572 if (pfound->flag) 00573 { 00574 *(pfound->flag) = pfound->val; 00575 return 0; 00576 } 00577 return pfound->val; 00578 } 00579 00580 /* Can't find it as a long option. If this is not getopt_long_only, 00581 or the option starts with '--' or is not a valid short 00582 option, then it's an error. 00583 Otherwise interpret it as a short option. */ 00584 if (!long_only || argv[optind][1] == '-' 00585 || my_index (optstring, *nextchar) == NULL) 00586 { 00587 if (opterr) 00588 { 00589 if (argv[optind][1] == '-') 00590 /* --option */ 00591 fprintf (stderr, gettext ("%s: unrecognized option `--%s'\n"), 00592 argv[0], nextchar); 00593 else 00594 /* +option or -option */ 00595 fprintf (stderr, gettext ("%s: unrecognized option `%c%s'\n"), 00596 argv[0], argv[optind][0], nextchar); 00597 } 00598 nextchar = (char *) ""; 00599 optind++; 00600 return '?'; 00601 } 00602 } 00603 00604 /* Look at and handle the next short option-character. */ 00605 00606 { 00607 char c = *nextchar++; 00608 char *temp = my_index (optstring, c); 00609 00610 /* Increment `optind' when we start to process its last character. */ 00611 if (*nextchar == '\0') 00612 ++optind; 00613 00614 if (temp == NULL || c == ':') 00615 { 00616 if (opterr) 00617 { 00618 if (posixly_correct) 00619 /* 1003.2 specifies the format of this message. */ 00620 fprintf (stderr, gettext ("%s: illegal option -- %c\n"), 00621 argv[0], c); 00622 else 00623 fprintf (stderr, gettext ("%s: invalid option -- %c\n"), 00624 argv[0], c); 00625 } 00626 optopt = c; 00627 return '?'; 00628 } 00629 if (temp[1] == ':') 00630 { 00631 if (temp[2] == ':') 00632 { 00633 /* This is an option that accepts an argument optionally. */ 00634 if (*nextchar != '\0') 00635 { 00636 optarg = nextchar; 00637 optind++; 00638 } 00639 else 00640 optarg = NULL; 00641 nextchar = NULL; 00642 } 00643 else 00644 { 00645 /* This is an option that requires an argument. */ 00646 if (*nextchar != '\0') 00647 { 00648 optarg = nextchar; 00649 /* If we end this ARGV-element by taking the rest as an arg, 00650 we must advance to the next element now. */ 00651 optind++; 00652 } 00653 else if (optind == argc) 00654 { 00655 if (opterr) 00656 { 00657 /* 1003.2 specifies the format of this message. */ 00658 fprintf (stderr, 00659 gettext ("%s: option requires an argument -- %c\n"), 00660 argv[0], c); 00661 } 00662 optopt = c; 00663 if (optstring[0] == ':') 00664 c = ':'; 00665 else 00666 c = '?'; 00667 } 00668 else 00669 /* We already incremented `optind' once; 00670 increment it again when taking next ARGV-elt as argument. */ 00671 optarg = argv[optind++]; 00672 nextchar = NULL; 00673 } 00674 } 00675 return c; 00676 } 00677 } 00678 00679 int 00680 getopt (argc, argv, optstring) 00681 int argc; 00682 char *const *argv; 00683 const char *optstring; 00684 { 00685 return _getopt_internal (argc, argv, optstring, 00686 (const struct option *) 0, 00687 (int *) 0, 00688 0); 00689 } 00690 00691 #endif /* _LIBC or not __GNU_LIBRARY__. */ 00692 00693 #ifdef TEST 00694 00695 /* Compile with -DTEST to make an executable for use in testing 00696 the above definition of `getopt'. */ 00697 00698 int 00699 main (argc, argv) 00700 int argc; 00701 char **argv; 00702 { 00703 int c; 00704 int digit_optind = 0; 00705 00706 while (1) 00707 { 00708 int this_option_optind = optind ? optind : 1; 00709 00710 c = getopt (argc, argv, "abc:d:0123456789"); 00711 if (c == EOF) 00712 break; 00713 00714 switch (c) 00715 { 00716 case '0': 00717 case '1': 00718 case '2': 00719 case '3': 00720 case '4': 00721 case '5': 00722 case '6': 00723 case '7': 00724 case '8': 00725 case '9': 00726 if (digit_optind != 0 && digit_optind != this_option_optind) 00727 printf ("digits occur in two different argv-elements.\n"); 00728 digit_optind = this_option_optind; 00729 printf ("option %c\n", c); 00730 break; 00731 00732 case 'a': 00733 printf ("option a\n"); 00734 break; 00735 00736 case 'b': 00737 printf ("option b\n"); 00738 break; 00739 00740 case 'c': 00741 printf ("option c with value `%s'\n", optarg); 00742 break; 00743 00744 case '?': 00745 break; 00746 00747 default: 00748 printf ("?? getopt returned character code 0%o ??\n", c); 00749 } 00750 } 00751 00752 if (optind < argc) 00753 { 00754 printf ("non-option ARGV-elements: "); 00755 while (optind < argc) 00756 printf ("%s ", argv[optind++]); 00757 printf ("\n"); 00758 } 00759 00760 exit (0); 00761 } 00762 00763 #endif /* TEST */