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: getopt.c.src.html,v 1.6 2006/01/18 05:35:11 rkowen Exp $";
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  | 
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  | 
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  | 
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  | 
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 | 
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 | 
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 | 
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 | 
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 */