1 /*****
2 ** ** Module Header ******************************************************* **
3 ** **
4 ** Modules Revision 3.0 **
5 ** Providing a flexible user environment **
6 ** **
7 ** File: getopt.c **
8 ** First Edition: 1995/12/20 **
9 ** **
10 ** Authors: Jens Hamisch, jens@Strawberry.COM **
11 ** **
12 ** Description: getopt procedure for the Modules package **
13 ** **
14 ** Exports: getopt Recognition of commadn line options **
15 ** **
16 ** Notes: This is based on the 'Getopt for GNU' from the gcc-2.7.2 **
17 ** compiler. It is preferred to the libc version, because it **
18 ** provides 'long-options'. **
19 ** **
20 ** ************************************************************************ **
21 ****/
22 /** **/
23 /** Getopt for GNU. **/
24 /** NOTE: getopt is now part of the C library, so if you don't know what **/
25 /** "Keep this file name-space clean" means, talk to roland"@gnu.ai.mit.edu **/
26 /** before changing it! **/
27 /** **/
28 /** Copyright( C) 1987, 88, 89, 90, 91, 92, 93, 94, 95 **/
29 /** Free Software Foundation, Inc. **/
30 /** **/
31 /** This program is free software; you can redistribute it and/or modify **/
32 /** it under the terms of the GNU General Public License as published by **/
33 /** the Free Software Foundation; either version 2, or( at your option) **/
34 /** any later version. **/
35 /** **/
36 /** This program is distributed in the hope that it will be useful, **/
37 /** but WITHOUT ANY WARRANTY; without even the implied warranty of **/
38 /** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **/
39 /** GNU General Public License for more details. **/
40 /** **/
41 /** You should have received a copy of the GNU General Public License **/
42 /** along with this program; if not, write to the Free Software **/
43 /** Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. **/
44 /** **/
45 /** ************************************************************************ **/
46
47 /** ** Copyright *********************************************************** **
48 ** **
49 ** Copyright 1991-1994 by John L. Furlan. **
50 ** see LICENSE.GPL, which must be provided, for details **
51 ** **
52 ** ************************************************************************ **/
53
54 static char Id[] = "@(#)$Id: 70c17cc67df8607445a45be72dde339b54581948 $";
55 static void *UseId[] = { &UseId, Id };
56
57 /** ************************************************************************ **/
58 /** CONFIGURATION **/
59 /** ************************************************************************ **/
60
61 /**
62 ** This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
63 ** Ditto for AIX 3.2 and <stdlib.h>.
64 **/
65
66 #ifndef _NO_PROTO
67 # define _NO_PROTO
68 #endif
69
70 #ifdef HAVE_CONFIG_H
71 # include <config.h>
72 #endif
73
74 /**
75 ** This is a separate conditional since some stdc systems
76 ** reject `defined( const)'.
77 **/
78
79 #if !defined( __STDC__) || !__STDC__
80 # ifndef const
81 # define const
82 # endif
83 #endif
84
85 /** ************************************************************************ **/
86 /** HEADERS **/
87 /** ************************************************************************ **/
88
89 #include <stdio.h>
90
91 /**
92 ** Comment out all this code if we are using the GNU C Library, and are not
93 ** actually compiling the library itself. This code is part of the GNU C
94 ** Library, but also included in many other GNU distributions. Compiling
95 ** and linking in this code is a waste when using the GNU C library
96 ** ( especially if it is a shared library). Rather than having every GNU
97 ** program understand `configure --with-gnu-libc' and omit the object files,
98 ** it is simpler to just do this in the source for each such file.
99 **
100 ** All this conditional nonsense has been commented out, because this
101 ** version of getopt has some module specific error handling that gets
102 ** tested during the check. It's a nice sentiment, but it doesn't buy
103 ** you much to not include this code in.
104 **/
105
106 /**
107 ** This needs to come after some library #include
108 ** to get __GNU_LIBRARY__ defined.
109 **/
110
111 /* #if defined( _LIBC) || !defined (__GNU_LIBRARY__) */
112
113 /**
114 ** Don't include stdlib.h for non-GNU C libraries because some of them
115 ** contain conflicting prototypes for getopt.
116 **/
117
118 # ifdef __GNU_LIBRARY__
119 # include <stdlib.h>
120 # endif /* GNU C library. */
121
122 /**
123 ** This is for other GNU distributions with internationalized messages.
124 ** When compiling libc, the _ macro is predefined.
125 **/
126
127 # ifndef _
128 # ifdef HAVE_LIBINTL_H
129 # include <libintl.h>
130 # define _(msgid) gettext( msgid)
131 # else
132 # define _(msgid) (msgid)
133 # endif
134 # endif
135
136 /**
137 ** This version of `getopt' appears to the caller like standard Unix `getopt'
138 ** but it behaves differently for the user, since it allows the user
139 ** to intersperse the options with the other arguments.
140 **
141 ** As `getopt' works, it permutes the elements of ARGV so that,
142 ** when it is done, all the options precede everything else. Thus
143 ** all application programs are extended to handle flexible argument order.
144 **
145 ** Setting the environment variable POSIXLY_CORRECT disables permutation.
146 ** Then the behavior is completely standard.
147 **
148 ** GNU application programs can use a third alternative mode in which
149 ** they can distinguish the relative order of options and other arguments.
150 **/
151
152 # include "getopt.h"
153
154 /**
155 ** We want to avoid inclusion of string.h with non-GNU libraries
156 ** because there are many ways it can cause trouble.
157 ** On some systems, it contains special magic macros that don't work
158 ** in GCC.
159 **/
160
161 # ifdef __GNU_LIBRARY__
162 # include <string.h>
163 # define my_index strchr
164 # else
165
166 /**
167 ** Avoid depending on library functions or files whose names are
168 ** inconsistent.
169 **/
170
171 char *getenv();
172
my_index(const char * str,int chr)173 static char *my_index( const char *str, int chr)
174 {
175 while( *str) {
176 if( *str == chr)
177 return( char *) str;
178 str++;
179 }
180 return( 0);
181 }
182
183 /**
184 ** If using GCC, we can safely declare strlen this way.
185 ** If not using GCC, it is ok not to declare it.
186 **
187 ** Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
188 ** That was relevant to code that was here before.
189 **/
190
191 # ifdef __GNUC__
192 # if !defined( __STDC__) || !__STDC__
193
194 /**
195 ** gcc with -traditional declares the built-in strlen to return int,
196 ** and has done so at least since version 2.4.5. -- rms.
197 **/
198
199 extern int strlen( const char *);
200 # endif /* not __STDC__ */
201 # endif /* __GNUC__ */
202
203 # endif /* not __GNU_LIBRARY__ */
204
205 /**
206 ** Include the modules header in order to get all error messages
207 **/
208
209 #include "modules_def.h"
210
211 /** ************************************************************************ **/
212 /** LOCAL DATATYPES **/
213 /** ************************************************************************ **/
214
215 /** not applicable **/
216
217 /** ************************************************************************ **/
218 /** CONSTANTS **/
219 /** ************************************************************************ **/
220
221 /** not applicable **/
222
223 /** ************************************************************************ **/
224 /** MACROS **/
225 /** ************************************************************************ **/
226
227 /** not applicable **/
228
229 /** ************************************************************************ **/
230 /** GLOBAL DATA **/
231 /** ************************************************************************ **/
232
233 /**
234 ** The following is required for compiling the TEST environment for the
235 ** modules package
236 **/
237
238 #ifdef _MODULES_DEF_H
239 # ifdef TEST
240 char *g_current_module = "getopt";
241 int linenum = 0;
242 # endif
243 #endif /** _MODULES_DEF_H **/
244
245 /**
246 ** For communication from `getopt' to the caller. When `getopt' finds an
247 ** option that takes an argument, the argument value is returned here.
248 ** Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element
249 ** is returned here.
250 **/
251
252 char *optarg = NULL;
253
254 /**
255 ** Index in ARGV of the next element to be scanned. This is used for
256 ** communication to and from the caller and for communication between
257 ** successive calls to `getopt'.
258 **
259 ** On entry to `getopt', zero means this is the first call; initialize.
260 **
261 ** When `getopt' returns EOF, this is the index of the first of the
262 ** non-option elements that the caller should itself scan.
263 **
264 ** Otherwise, `optind' communicates from one call to the next
265 ** how much of ARGV has been scanned so far.
266 **/
267
268 /**
269 ** XXX 1003.2 says this must be 1 before any call.
270 **/
271
272 int optind = 0;
273
274 /**
275 ** Callers store zero here to inhibit the error message for unrecognized
276 ** options.
277 **/
278
279 int opterr = 1;
280
281 /**
282 ** Set to an option character which was unrecognized.
283 ** This must be initialized on some systems to avoid linking in the
284 ** system's own getopt implementation.
285 **/
286
287 int optopt = '?';
288
289 /** ************************************************************************ **/
290 /** LOCAL DATA **/
291 /** ************************************************************************ **/
292
293 #ifdef _MODULES_DEF_H
294
295 /**
296 ** Runtime information for the modules package
297 **/
298
299 static char module_name[] = "getopt.c"; /** File name of this module **/
300
301 #ifdef _MODULES_DEF_H
302 # if WITH_DEBUGGING_INIT
303 static char _proc_exchange[] = "exchange";
304 static char _proc_getopt_initialize[] = "_getopt_initialize";
305 static char _proc_getopt_internal[] = " _getopt_internal";
306 static char _proc_getopt[] = "getopt";
307 static char _proc_getopt_long[] = "getopt_long";
308 static char _proc_getopt_long_only[] = "getopt_long_only";
309 # endif
310 #endif
311
312 # ifdef TEST
313 static char _proc_main[] = "main";
314 # endif
315
316 #endif /** _MODULES_DEF_H **/
317
318 /**
319 ** The next char to be scanned in the option-element in which the last
320 ** option character we returned was found. This allows us to pick up
321 ** the scan where we left off.
322 **
323 ** If this is zero, or a null string, it means resume the scan by advan-
324 ** cing to the next ARGV-element.
325 **/
326
327 static char *nextchar;
328
329 /**
330 ** Describe how to deal with options that follow non-option ARGV-elements.
331 **
332 ** If the caller did not specify anything, the default is REQUIRE_ORDER if
333 ** the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise.
334 **
335 ** REQUIRE_ORDER means don't recognize them as options;
336 ** stop option processing when the first non-option is seen.
337 ** This is what Unix does.
338 ** This mode of operation is selected by either setting the environment
339 ** variable POSIXLY_CORRECT, or using `+' as the first character
340 ** of the list of option characters.
341 **
342 ** PERMUTE is the default. We permute the contents of ARGV as we scan,
343 ** so that eventually all the non-options are at the end. This allows options
344 ** to be given in any order, even with programs that were not written to
345 ** expect this.
346 **
347 ** RETURN_IN_ORDER is an option available to programs that were written
348 ** to expect options and other ARGV-elements in any order and that care about
349 ** the ordering of the two. We describe each non-option ARGV-element
350 ** as if it were the argument of an option with character code 1.
351 ** Using `-' as the first character of the list of option characters
352 ** selects this mode of operation.
353 **
354 ** The special argument `--' forces an end of option-scanning regardless
355 ** of the value of `ordering'. In the case of RETURN_IN_ORDER, only
356 ** `--' can cause `getopt' to return EOF with `optind' != ARGC.
357 **/
358
359 static enum {
360 REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
361 } ordering;
362
363 /**
364 ** Value of POSIXLY_CORRECT environment variable.
365 **/
366
367 static char *posixly_correct;
368
369 /**
370 ** Handle permutation of arguments.
371 **/
372
373 /**
374 ** Describe the part of ARGV that contains non-options that have
375 ** been skipped. `first_nonopt' is the index in ARGV of the first of them;
376 ** `last_nonopt' is the index after the last of them.
377 **/
378
379 static int first_nonopt;
380 static int last_nonopt;
381
382 /** ************************************************************************ **/
383 /** PROTOTYPES **/
384 /** ************************************************************************ **/
385
386 static void exchange( char **argv);
387 static const char *_getopt_initialize( const char *optstring);
388 static int _getopt_internal( int argc,
389 char *const *argv,
390 const char *optstring,
391 const struct option *longopts,
392 int *longind,
393 int long_only);
394
395 /*++++
396 ** ** Function-Header ***************************************************** **
397 ** **
398 ** Function: exchange **
399 ** **
400 ** Description: Exchange two adjacent subsequences of ARGV. **
401 ** One subsequence is elements( first_nonopt, **
402 ** last_nonopt) which contains all the non-options that **
403 ** have been skipped so far. The other is elements **
404 ** (last_nonopt,optind), which contains all the options **
405 ** processed since those non-options were skipped. **
406 ** **
407 ** `first_nonopt' and `last_nonopt' are relocated so **
408 ** that they describe the new indices of the non-options**
409 ** in ARGV after they are moved. **
410 ** **
411 ** First Edition: 1995/12/20 **
412 ** **
413 ** Parameters: char **argv Command line arguments **
414 ** **
415 ** Result: argv ARGV array with exchanged sequences **
416 ** **
417 ** Attached Globals: first_nonopt first and last non option argument **
418 ** last_nonopt on the stream before and after the **
419 ** change.( I/O parameter) **
420 ** **
421 ** ************************************************************************ **
422 ++++*/
423
exchange(char ** argv)424 static void exchange( char **argv)
425 {
426 int bottom = first_nonopt;
427 int middle = last_nonopt;
428 int top = optind;
429 char *tem;
430
431 #ifdef _MODULES_DEF_H
432 # if WITH_DEBUGGING_INIT
433 ErrorLogger( NO_ERR_START, LOC, _proc_exchange, NULL);
434 # endif
435 #endif
436
437 /**
438 ** Exchange the shorter segment with the far end of the longer segment.
439 ** That puts the shorter segment into the right place.
440 ** It leaves the longer segment in the right place overall,
441 ** but it consists of two parts that need to be swapped next.
442 **/
443
444 while( top > middle && middle > bottom) {
445 if( top - middle > middle - bottom) {
446
447 /**
448 ** Bottom segment is the short one.
449 **/
450
451 int len = middle - bottom;
452 register int i;
453
454 /**
455 ** Swap it with the top part of the top segment.
456 **/
457
458 for( i = 0; i < len; i++) {
459 tem = argv[bottom + i];
460 argv[bottom + i] = argv[top -( middle - bottom) + i];
461 argv[top -( middle - bottom) + i] = tem;
462 }
463
464 /**
465 ** Exclude the moved bottom segment from further swapping.
466 **/
467
468 top -= len;
469
470 } else {
471
472 /**
473 ** Top segment is the short one.
474 **/
475
476 int len = top - middle;
477 register int i;
478
479 /**
480 ** Swap it with the bottom part of the bottom segment.
481 **/
482
483 for( i = 0; i < len; i++) {
484 tem = argv[bottom + i];
485 argv[bottom + i] = argv[middle + i];
486 argv[middle + i] = tem;
487 }
488
489 /**
490 ** Exclude the moved top segment from further swapping.
491 **/
492
493 bottom += len;
494 }
495
496 } /** while **/
497
498 /**
499 ** Update records for the slots the non-options now occupy.
500 **/
501
502 first_nonopt +=( optind - last_nonopt);
503 last_nonopt = optind;
504
505 #ifdef _MODULES_DEF_H
506 # if WITH_DEBUGGING_INIT
507 ErrorLogger( NO_ERR_END, LOC, _proc_exchange, NULL);
508 # endif
509 #endif
510
511 } /** end of 'exchange' **/
512
513 /*++++
514 ** ** Function-Header ***************************************************** **
515 ** **
516 ** Function: _getopt_initialize **
517 ** **
518 ** Description: Initialize the internal data when the first call is **
519 ** made **
520 ** This defines how to proceed if options and non-op- **
521 ** tions are mixed up. See definition of the enum **
522 ** 'ordering' for further explanation. **
523 ** **
524 ** First Edition: 1995/12/20 **
525 ** **
526 ** Parameters: char *optstring Options string **
527 ** **
528 ** Result: argv ARGV array with exchanged sequences **
529 ** **
530 ** Attached globals: first_nonopt, First an las position of **
531 ** last_nonopt non-option arguments **
532 ** optind Option scan index **
533 ** nextchar Next character to scan **
534 ** posixly_correct Value of the environment **
535 ** variable 'POSIXLY_CORRECT' **
536 ** ordering Ordering method ... **
537 ** **
538 ** ************************************************************************ **
539 ++++*/
540
_getopt_initialize(const char * optstring)541 static const char *_getopt_initialize( const char *optstring)
542 {
543
544 #ifdef _MODULES_DEF_H
545 # if WITH_DEBUGGING_INIT
546 ErrorLogger( NO_ERR_START, LOC, _proc_getopt_initialize, NULL);
547 # endif
548 #endif
549
550 /**
551 ** Start processing options with ARGV-element 1( since ARGV-element 0
552 ** is the program name); the sequence of previously skipped
553 ** non-option ARGV-elements is empty.
554 **/
555
556 first_nonopt = last_nonopt = optind = 1;
557 nextchar = NULL;
558 posixly_correct = getenv( "POSIXLY_CORRECT");
559
560 /**
561 ** Determine how to handle the ordering of options and nonoptions.
562 **/
563
564 if( optstring[0] == '-') {
565 ordering = RETURN_IN_ORDER;
566 ++optstring;
567
568 } else if( optstring[0] == '+') {
569 ordering = REQUIRE_ORDER;
570 ++optstring;
571
572 } else if( posixly_correct != NULL)
573 ordering = REQUIRE_ORDER;
574
575 else
576 ordering = PERMUTE;
577
578 #ifdef _MODULES_DEF_H
579 # if WITH_DEBUGGING_INIT
580 ErrorLogger( NO_ERR_END, LOC, _proc_getopt_initialize, NULL);
581 # endif
582 #endif
583
584 return( optstring);
585
586 } /** End of '_getopt_initialize' **/
587
588 /*++++
589 ** ** Function-Header ***************************************************** **
590 ** **
591 ** Function: _getopt_internal **
592 ** **
593 ** Description: Scan elements of ARGV( whose length is ARGC) for **
594 ** option characters given in OPTSTRING. **
595 ** or long-options specified in the longopt array **
596 ** **
597 ** First Edition: 1995/12/20 **
598 ** **
599 ** Parameters: int argc, # of arguments **
600 ** char **argv, ARGV array **
601 ** char *optstring, String of valid **
602 ** short options **
603 ** struct option *longopts, Table of valid long **
604 ** options **
605 ** int *longind, Returns the index of **
606 ** the found long opt. **
607 ** int long_only Search long options **
608 ** only **
609 ** **
610 ** Result: int '?' Parse error **
611 ** 0 Long option w/o argument found **
612 ** else short option that has been found **
613 ** or the value of a long option **
614 ** EOF no more arguments on ARGV **
615 ** **
616 ** Attached globals: optind Index of the current option in the **
617 ** ARGV array **
618 ** optarg Argument of an option with value **
619 ** **
620 ** ************************************************************************ **
621 ++++*/
622 /** **/
623 /** If an element of ARGV starts with '-', and is not exactly "-" or "--", **/
624 /** then it is an option element. The characters of this element **/
625 /** ( aside from the initial '-') are option characters. If `getopt' **/
626 /** is called repeatedly, it returns successively each of the option **/
627 /** characters from each of the option elements. **/
628 /** **/
629 /** If `getopt' finds another option character, it returns that character, **/
630 /** updating `optind' and `nextchar' so that the next call to `getopt' can **/
631 /** resume the scan with the following option character or ARGV-element. **/
632 /** **/
633 /** If there are no more option characters, `getopt' returns `EOF'. **/
634 /** Then `optind' is the index in ARGV of the first ARGV-element **/
635 /** that is not an option. ( The ARGV-elements have been permuted **/
636 /** so that those that are not options now come last.) **/
637 /** **/
638 /** OPTSTRING is a string containing the legitimate option characters. **/
639 /** If an option character is seen that is not listed in OPTSTRING, **/
640 /** return '?' after printing an error message. If you set `opterr' to **/
641 /** zero, the error message is suppressed but we still return '?'. **/
642 /** **/
643 /** If a char in OPTSTRING is followed by a colon, that means it wants an **/
644 /** arg, so the following text in the same ARGV-element, or the text of **/
645 /** the following ARGV-element, is returned in `optarg'. Two colons mean **/
646 /** an option that wants an optional arg; if there is text in the current **/
647 /** ARGV-element, it is returned in `optarg', otherwise `optarg' is set to **/
648 /** zero. **/
649 /** **/
650 /** If OPTSTRING starts with `-' or `+', it requests different methods of **/
651 /** handling the non-option ARGV-elements. **/
652 /** See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. **/
653 /** **/
654 /** Long-named options begin with `--' instead of `-'. **/
655 /** Their names may be abbreviated as long as the abbreviation is unique **/
656 /** or is an exact match for some defined option. If they have an **/
657 /** argument, it follows the option name in the same ARGV-element, **/
658 /** separated from the option name by a `=', or else the in next ARGV- **/
659 /** element. When `getopt' finds a long-named option, it returns 0 if **/
660 /** that option's `flag' field is nonzero, the value of the option's `val' **/
661 /** field if the `flag' field is zero. **/
662 /** **/
663 /** The elements of ARGV aren't really const, because we permute them. **/
664 /** But we pretend they're const in the prototype to be compatible **/
665 /** with other systems. **/
666 /** **/
667 /** LONGOPTS is a vector of `struct option' terminated by an **/
668 /** element containing a name which is zero. **/
669 /** **/
670 /** LONGIND returns the index in LONGOPT of the long-named option found. **/
671 /** It is only valid when a long-named option has been found by the most **/
672 /** recent call. **/
673 /** **/
674 /** If LONG_ONLY is nonzero, '-' as well as '--' can introduce **/
675 /** long-named options. **/
676 /** **/
677 /** ************************************************************************ **/
678
_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int long_only)679 static int _getopt_internal( int argc,
680 char *const *argv,
681 const char *optstring,
682 const struct option *longopts,
683 int *longind,
684 int long_only)
685 {
686 optarg = NULL;
687
688 #ifdef _MODULES_DEF_H
689 # if WITH_DEBUGGING_INIT
690 ErrorLogger( NO_ERR_START, LOC, _proc_getopt_internal, NULL);
691 # endif
692 #endif
693
694 /**
695 ** Initialization
696 **/
697
698 if( optind == 0) {
699 optstring = _getopt_initialize( optstring);
700 optind = 1; /** Don't scan ARGV[0], the program name. **/
701 }
702
703 if( nextchar == NULL || *nextchar == '\0') {
704
705 /**
706 ** Advance to the next ARGV-element.
707 **/
708
709 if( ordering == PERMUTE) {
710
711 /**
712 ** If we have just processed some options following some non-
713 ** options, exchange them so that the options come first.
714 **/
715
716 if( first_nonopt != last_nonopt && last_nonopt != optind)
717 exchange( (char **) argv);
718 else if( last_nonopt != optind)
719 first_nonopt = optind;
720
721 /**
722 ** Skip any additional non-options and extend the range of
723 ** non-options previously skipped.
724 **/
725
726 while( optind < argc &&
727 ( argv[optind][0] != '-' || argv[optind][1] == '\0'))
728 optind++;
729
730 last_nonopt = optind;
731 }
732
733 /**
734 ** The special ARGV-element `--' means premature end of options.
735 ** Skip it like a null option, then exchange with previous non-
736 ** options ** as if it were an option, then skip everything else
737 ** like a non-option.
738 **/
739
740 if( optind != argc && !strcmp( argv[optind], "--")) {
741
742 optind++;
743
744 if( first_nonopt != last_nonopt && last_nonopt != optind)
745 exchange((char **) argv);
746 else if( first_nonopt == last_nonopt)
747 first_nonopt = optind;
748
749 last_nonopt = argc;
750
751 optind = argc;
752 }
753
754 /**
755 ** If we have done all the ARGV-elements, stop the scan and back
756 ** over any non-options that we skipped and permuted.
757 **/
758
759 if( optind == argc) {
760
761 /**
762 ** Set the next-arg-index to point at the non-options that we
763 ** previously skipped, so the caller will digest them.
764 **/
765
766 if( first_nonopt != last_nonopt)
767 optind = first_nonopt;
768
769 return( EOF);
770 }
771
772 /**
773 ** If we have come to a non-option and did not permute it,
774 ** either stop the scan or describe it to the caller and pass it by.
775 **/
776
777 if( argv[optind][0] != '-' || argv[optind][1] == '\0') {
778
779 if( ordering == REQUIRE_ORDER)
780 return EOF;
781 optarg = argv[optind++];
782
783 return( 1);
784 }
785
786 /**
787 ** We have found another option-ARGV-element.
788 ** Skip the initial punctuation.
789 **/
790
791 nextchar =( argv[optind] + 1 +
792 ( longopts != NULL && argv[optind][1] == '-'));
793 }
794
795 /**
796 ** Decode the current option-ARGV-element.
797 **/
798
799 /**
800 ** Check whether the ARGV-element is a long option.
801 **
802 ** If long_only and the ARGV-element has the form "-f", where f is
803 ** a valid short option, don't consider it an abbreviated form of
804 ** a long option that starts with f. Otherwise there would be no
805 ** way to give the -f short option.
806 **
807 ** On the other hand, if there's a long option "fubar" and
808 ** the ARGV-element is "-fu", do consider that an abbreviation of
809 ** the long option, just like "--fu", and not "-f" with arg "u".
810 **
811 ** This distinction seems to be the most useful approach.
812 **/
813
814 if( longopts != NULL &&( argv[optind][1] == '-' ||
815 ( long_only &&
816 ( argv[optind][2] || !my_index (optstring, argv[optind][1]))))) {
817
818 char *nameend;
819 const struct option *p;
820 const struct option *pfound = NULL;
821 int exact = 0;
822 int ambig = 0;
823 int indfound;
824 int option_index;
825
826 /**
827 ** Skip the remaining characters of the long option upt to its
828 ** names end( End of the option itsself or the '=' sign)
829 **/
830
831 for( nameend = nextchar; *nameend && *nameend != '='; nameend++);
832
833 /**
834 ** Test all long options for either exact match or abbreviated
835 ** matches.
836 **/
837
838 for( p = longopts, option_index = 0; p->name; p++, option_index++) {
839 if( !strncmp( p->name, nextchar, nameend - nextchar)) {
840
841 if( nameend - nextchar == strlen( p->name)) {
842
843 /**
844 ** Exact match found.
845 **/
846
847 pfound = p;
848 indfound = option_index;
849 exact = 1;
850 break;
851
852 } else if( pfound == NULL) {
853
854 /**
855 ** First nonexact match found.
856 **/
857
858 pfound = p;
859 indfound = option_index;
860
861 } else
862
863 /**
864 ** Second or later nonexact match found.
865 **/
866
867 ambig = 1;
868
869 } /** if( !strncmp) **/
870 } /** for **/
871
872 /**
873 ** Print an error message for ambigious abbreviations and exit
874 ** on error
875 **/
876
877 if( ambig && !exact) {
878
879 if( opterr)
880 #ifdef _MODULES_DEF_H
881 ErrorLogger( ERR_OPT_AMBIG, LOC, argv[optind], NULL);
882 #else
883 fprintf( stderr, _("%s: option `%s' is ambiguous\n"),
884 argv[0], argv[optind]);
885 #endif
886
887 nextchar += strlen( nextchar);
888 optind++;
889 return( '?');
890 }
891
892 /**
893 ** Longname found ?
894 **/
895
896 if( pfound != NULL) {
897
898 option_index = indfound;
899 optind++;
900
901 /**
902 ** *nameend is != NULL if there is a value specified for
903 ** the option: '--option=value' -> *nameend = '='
904 **/
905
906 if( *nameend) {
907
908 /**
909 ** Don't test has_arg with >, because some C compilers don't
910 ** allow it to be used on enums.
911 **/
912
913 if( pfound->has_arg)
914 optarg = nameend + 1;
915
916 else {
917
918 if( opterr)
919
920 /**
921 ** ERROR: --option w/o argument
922 **/
923
924 if( argv[optind - 1][1] == '-')
925 #ifdef _MODULES_DEF_H
926 ErrorLogger( ERR_OPT_NOARG, LOC, pfound->name, NULL);
927 #else
928 fprintf( stderr,
929 _("%s: option `--%s' doesn't allow an argument\n"),
930 argv[0], pfound->name);
931 #endif
932
933 /**
934 ** ERROR: +option or -option w/o argument
935 **/
936
937 else {
938 #ifdef _MODULES_DEF_H
939 char buffer[ BUFSIZ];
940 sprintf( buffer, "%c%s", argv[optind - 1][0], pfound->name);
941 ErrorLogger( ERR_OPT_NOARG, LOC, buffer, NULL);
942 #else
943 fprintf( stderr,
944 _("%s: option `%c%s' doesn't allow an argument\n"),
945 argv[0], argv[optind - 1][0], pfound->name);
946 #endif
947 }
948
949 nextchar += strlen( nextchar);
950 return( '?');
951 }
952
953 /**
954 ** Options with arguments
955 **/
956
957 } else if( pfound->has_arg == 1) {
958
959 if( optind < argc)
960 optarg = argv[optind++];
961
962 else {
963
964 /**
965 ** ERROR: Option without argument where one is required
966 **/
967
968 if( opterr)
969 #ifdef _MODULES_DEF_H
970 ErrorLogger( ERR_OPT_REQARG, LOC, argv[optind-1], NULL);
971 #else
972 fprintf( stderr,
973 _("%s: option `%s' requires an argument\n"),
974 argv[0], argv[optind - 1]);
975 #endif
976
977 nextchar += strlen( nextchar);
978 return((optstring[0] == ':') ? ':' : '?');
979 }
980 }
981
982 /**
983 ** Return the indication, that a long vlaue has been found
984 ** and set up pointers for the next option expansion
985 **/
986
987 nextchar += strlen( nextchar);
988
989 if( longind != NULL)
990 *longind = option_index;
991
992 if( pfound->flag) {
993 *(pfound->flag) = pfound->val;
994 return( 0);
995 }
996 return( pfound->val);
997 }
998
999 /**
1000 ** Can't find it as a long option. If this is not getopt_long_only,
1001 ** or the option starts with '--' or is not a valid short
1002 ** option, then it's an error.
1003 ** Otherwise interpret it as a short option.
1004 **/
1005
1006 if( !long_only || argv[optind][1] == '-' ||
1007 my_index( optstring, *nextchar) == NULL) {
1008
1009 if( opterr) {
1010
1011 /**
1012 ** ERROR: unrecognized --option
1013 **/
1014
1015 if( argv[optind][1] == '-') {
1016 #ifdef _MODULES_DEF_H
1017 ErrorLogger( ERR_OPT_UNKNOWN, LOC, nextchar, NULL);
1018 #else
1019 fprintf( stderr, _("%s: unrecognized option `--%s'\n"),
1020 argv[0], nextchar);
1021 #endif
1022
1023 /**
1024 ** ERROR: unrecognized +option or -option
1025 **/
1026
1027 } else {
1028 #ifdef _MODULES_DEF_H
1029 char buffer[ BUFSIZ];
1030 sprintf( buffer, "%c%s", argv[optind][0], nextchar);
1031 ErrorLogger( ERR_OPT_AMBIG, LOC, buffer, NULL);
1032 #else
1033 fprintf( stderr, _("%s: unrecognized option `%c%s'\n"),
1034 argv[0], argv[optind][0], nextchar);
1035 #endif
1036 }
1037 }
1038
1039 nextchar =( char *) "";
1040 optind++;
1041 return( '?');
1042 }
1043 } /** if( long option) **/
1044
1045 /**
1046 ** Look at and handle the next short option-character.
1047 **/
1048
1049 {
1050 char c = *nextchar++;
1051 char *temp = my_index( optstring, c);
1052
1053 /**
1054 ** Increment `optind' when we start to process its last character.
1055 **/
1056
1057 if( *nextchar == '\0')
1058 ++optind;
1059
1060 /**
1061 ** Unrecognized options
1062 **/
1063
1064 if( temp == NULL || c == ':') {
1065 if( opterr) {
1066
1067 #ifdef _MODULES_DEF_H
1068 char buffer[ 2];
1069 buffer[ 0] = c;
1070 buffer[ 1] = '\0';
1071 #endif
1072
1073 if( posixly_correct) {
1074
1075 /**
1076 ** 1003.2 specifies the format of this message.
1077 **/
1078
1079 #ifdef _MODULES_DEF_H
1080 ErrorLogger( ERR_OPT_ILL, LOC, buffer, NULL);
1081 #else
1082 fprintf( stderr, _("%s: illegal option -- %c\n"),
1083 argv[0], c);
1084 #endif
1085 } else {
1086 #ifdef _MODULES_DEF_H
1087 ErrorLogger( ERR_OPT_INV, LOC, buffer, NULL);
1088 #else
1089 fprintf( stderr, _("%s: invalid option -- %c\n"),
1090 argv[0], c);
1091 #endif
1092 }
1093 }
1094 optopt = c;
1095 return( '?');
1096 }
1097
1098 /**
1099 **
1100 **/
1101
1102 if( temp[1] == ':') {
1103 if( temp[2] == ':') {
1104
1105 /**
1106 ** This is an option that accepts an argument optionally.
1107 **/
1108
1109 if( *nextchar != '\0') {
1110 optarg = nextchar;
1111 optind++;
1112 } else
1113 optarg = NULL;
1114
1115 nextchar = NULL;
1116
1117 } else { /** optional argument **/
1118
1119 /**
1120 ** This is an option that requires an argument.
1121 **/
1122
1123 if( *nextchar != '\0') {
1124 optarg = nextchar;
1125
1126 /**
1127 ** If we end this ARGV-element by taking the rest as an arg,
1128 ** we must advance to the next element now.
1129 **/
1130
1131 optind++;
1132
1133 } else if( optind == argc) {
1134
1135 if( opterr) {
1136
1137 /**
1138 ** 1003.2 specifies the format of this message. *
1139 **/
1140
1141 #ifdef _MODULES_DEF_H
1142 char buffer[ 2];
1143 buffer[ 0] = c;
1144 buffer[ 1] = '\0';
1145 ErrorLogger( ERR_OPT_REQARG, LOC, buffer, NULL);
1146 #else
1147 fprintf( stderr,
1148 _("%s: option requires an argument -- %c\n"),
1149 argv[0], c);
1150 #endif
1151 }
1152
1153 optopt = c;
1154 if( optstring[0] == ':')
1155 c = ':';
1156 else
1157 c = '?';
1158
1159 } else
1160
1161 /**
1162 ** We already incremented `optind' once;
1163 ** increment it again when taking next ARGV-elt as argument.
1164 **/
1165
1166 optarg = argv[optind++];
1167 nextchar = NULL;
1168 }
1169 }
1170
1171 /**
1172 ** Now c contains the found character in case of success of '?' in case
1173 ** of failure
1174 **/
1175
1176 #ifdef _MODULES_DEF_H
1177 # if WITH_DEBUGGING_INIT
1178 ErrorLogger( NO_ERR_END, LOC, _proc_getopt_internal, NULL);
1179 # endif
1180 #endif
1181 return( c);
1182
1183 } /** block **/
1184
1185 } /** End of '_getopt_internal' **/
1186
1187 /*++++
1188 ** ** Function-Header ***************************************************** **
1189 ** **
1190 ** Function: getopt, getopt_long, getopt_long_only **
1191 ** **
1192 ** Description: Calls _getopt_internal in order to provide a normal **
1193 ** getopt call. **
1194 ** **
1195 ** First Edition: 1995/12/20 **
1196 ** **
1197 ** Parameters: int argc, # of arguments **
1198 ** char **argv, ARGV array **
1199 ** char *optstring, String of valid short opt. **
1200 ** **
1201 ** Result: int '?' Parse error **
1202 ** 0 Long option w/o argument found **
1203 ** else short option that has been found **
1204 ** or the value of a long option **
1205 ** EOF no more arguments on ARGV **
1206 ** **
1207 ** Attached globals: optind Index of the current option in the **
1208 ** ARGV array **
1209 ** optarg Argument of an option with value **
1210 ** opterr Set in case of parse errors **
1211 ** **
1212 ** ************************************************************************ **
1213 ++++*/
1214
getopt(int argc,char * const * argv,const char * optstring)1215 int getopt( int argc, char *const *argv, const char *optstring)
1216 {
1217
1218 #ifdef _MODULES_DEF_H
1219 # if WITH_DEBUGGING_INIT
1220 ErrorLogger( NO_ERR_START, LOC, _proc_getopt, NULL);
1221 # endif
1222 #endif
1223
1224 return _getopt_internal( argc, argv, optstring,
1225 ( const struct option *) 0,
1226 ( int *) 0,
1227 0);
1228 } /** End of 'getopt' **/
1229
getopt_long(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind)1230 int getopt_long( int argc, char *const *argv, const char *optstring,
1231 const struct option *longopts, int *longind)
1232 {
1233
1234 #ifdef _MODULES_DEF_H
1235 # if WITH_DEBUGGING_INIT
1236 ErrorLogger( NO_ERR_START, LOC, _proc_getopt_long, NULL);
1237 # endif
1238 #endif
1239
1240 return _getopt_internal( argc, argv, optstring, longopts, longind, 0);
1241
1242 } /** End of 'getopt' **/
1243
getopt_long_only(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind)1244 int getopt_long_only( int argc, char *const *argv, const char *optstring,
1245 const struct option *longopts, int *longind)
1246 {
1247
1248 #ifdef _MODULES_DEF_H
1249 # if WITH_DEBUGGING_INIT
1250 ErrorLogger( NO_ERR_START, LOC, _proc_getopt_long_only, NULL);
1251 # endif
1252 #endif
1253
1254 return _getopt_internal( argc, argv, optstring, longopts, longind, 1);
1255
1256 } /** End of 'getopt' **/
1257
1258 /* #endif */ /* _LIBC or not __GNU_LIBRARY__. */
1259
1260 #ifdef TEST
1261
1262 /*++++
1263 ** ** Function-Header ***************************************************** **
1264 ** **
1265 ** Function: main **
1266 ** **
1267 ** Description: Test procedure for getopt **
1268 ** Compile with -DTEST to make an executable for use in **
1269 ** testing the above definition of `getopt' **
1270 ** **
1271 ** First Edition: 1995/12/20 **
1272 ** **
1273 ** Parameters: int argc, # of arguments **
1274 ** char **argv, ARGV array **
1275 ** **
1276 ** Result: - **
1277 ** **
1278 ** ************************************************************************ **
1279 ++++*/
1280
main(int argc,char ** argv)1281 int main( int argc, char **argv)
1282 {
1283
1284 # ifdef _MODULES_DEF_H
1285 # if WITH_DEBUGGING_INIT
1286 ErrorLogger( NO_ERR_START, LOC, _proc_main, NULL);
1287 # endif
1288 # endif
1289
1290 int c;
1291 int digit_optind = 0;
1292 int longind;
1293 int option, verbose;
1294 char *value;
1295
1296 const struct option longopts[] = {
1297 { "test", no_argument, NULL, 0 },
1298 { "option", optional_argument, &option, 1 },
1299 { "verbose", optional_argument, NULL, 'v' },
1300 { "value", required_argument, NULL, 'x'},
1301 { NULL, no_argument, NULL, 0 }
1302 };
1303
1304 /**
1305 ** Print all options ...
1306 **/
1307
1308 while( 1) {
1309
1310 int this_option_optind = optind ? optind : 1;
1311
1312 c = getopt_long( argc, argv, "abc:d:0123456789", longopts, &longind);
1313 if( c == EOF)
1314 break; /** while( 1) **/
1315
1316 switch( c) {
1317
1318 case 0:
1319 printf( "option --test or --option\n");
1320 if( optarg)
1321 printf( "with argument '%s'", optarg);
1322 printf( "\n option is set to %d\n", option);
1323 break;
1324
1325 case '0':
1326 case '1':
1327 case '2':
1328 case '3':
1329 case '4':
1330 case '5':
1331 case '6':
1332 case '7':
1333 case '8':
1334 case '9':
1335 if( digit_optind != 0 && digit_optind != this_option_optind)
1336 printf( "digits occur in two different argv-elements.\n");
1337 digit_optind = this_option_optind;
1338 printf( "option %c\n", c);
1339 break;
1340
1341 case 'a':
1342 printf( "option a\n");
1343 break;
1344
1345 case 'b':
1346 printf( "option b\n");
1347 break;
1348
1349 case 'c':
1350 printf( "option c with value `%s'\n", optarg);
1351 break;
1352
1353 case 'v':
1354 case 'x':
1355 printf( "option %c ", c);
1356 if( optarg)
1357 printf( "with argument '%s'", optarg);
1358 printf( "\n");
1359 break;
1360
1361 case '?':
1362 break;
1363
1364 default:
1365 printf( "?? getopt returned character code 0%o ??\n", c);
1366 }
1367 } /** while( 1) **/
1368
1369 /**
1370 ** Finally print all remaining arguments
1371 **/
1372
1373 if( optind < argc) {
1374 printf( "non-option ARGV-elements: ");
1375 while( optind < argc)
1376 printf( "%s ", argv[optind++]);
1377 printf( "\n");
1378 }
1379
1380 /**
1381 ** Exit on success
1382 **/
1383
1384 # ifdef _MODULES_DEF_H
1385 # if WITH_DEBUGGING_INIT
1386 ErrorLogger( NO_ERR_END, LOC, _proc_main, NULL);
1387 # endif
1388 # endif
1389
1390 exit( 0);
1391
1392 } /** End of 'main' **/
1393
1394 #endif /* TEST */
1395