1 /* [argparse.c wk 17.06.97] Argument Parser for option handling
2 * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3 * 2004 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 * Note: This is an independent version of the one in WkLib
35 /*********************************
40 * char *argc; pointer to argc (value subject to change)
41 * char ***argv; pointer to argv (value subject to change)
42 * unsigned flags; Global flags (DO NOT CHANGE)
43 * int err; print error about last option
44 * 1 = warning, 2 = abort
45 * int r_opt; return option
46 * int r_type; type of return value (0 = no argument found)
57 * } internal; DO NOT CHANGE
62 * const char *long_opt;
66 * int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts );
69 * This is my replacement for getopt(). See the example for a typical usage.
71 * Bit 0 : Do not remove options form argv
72 * Bit 1 : Do not stop at last option but return other args
73 * with r_opt set to -1.
74 * Bit 2 : Assume options and real args are mixed.
75 * Bit 3 : Do not use -- to stop option processing.
76 * Bit 4 : Do not skip the first arg.
77 * Bit 5 : allow usage of long option with only one dash
78 * Bit 6 : ignore --version and --help
79 * all other bits must be set to zero, this value is modified by the
80 * function, so assume this is write only.
81 * Local flags (for each option):
82 * Bit 2-0 : 0 = does not take an argument
83 * 1 = takes int argument
84 * 2 = takes string argument
85 * 3 = takes long argument
86 * 4 = takes ulong argument
87 * Bit 3 : argument is optional (r_type will the be set to 0)
88 * Bit 4 : allow 0x etc. prefixed values.
89 * Bit 7 : this is a command and not an option
90 * You stop the option processing by setting opts to NULL, the function will
93 * Returns the args.r_opt or 0 if ready
94 * r_opt may be -2/-7 to indicate an unknown option/command.
98 * You do not need to process the options 'h', '--help' or '--version'
99 * because this function includes standard help processing; but if you
100 * specify '-h', '--help' or '--version' you have to do it yourself.
101 * The option '--' stops argument processing; if bit 1 is set the function
102 * continues to return normal arguments.
103 * To process float args or unsigned args you must use a string args and do
104 * the conversion yourself.
107 * ARGPARSE_OPTS opts[] = {
108 * { 'v', "verbose", 0 },
109 * { 'd', "debug", 0 },
110 * { 'o', "output", 2 },
111 * { 'c', "cross-ref", 2|8 },
112 * { 'm', "my-option", 1|8 },
113 * { 500, "have-no-short-option-for-this-long-option", 0 },
115 * ARGPARSE_ARGS pargs = { &argc, &argv, 0 }
117 * while( ArgParse( &pargs, &opts) ) {
118 * switch( pargs.r_opt ) {
119 * case 'v': opt.verbose++; break;
120 * case 'd': opt.debug++; break;
121 * case 'o': opt.outfile = pargs.r.ret_str; break;
122 * case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break;
123 * case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break;
124 * case 500: opt.a_long_one++; break
125 * default : pargs.err = 1; break; -- force warning output --
129 * log_fatal( "Too many args");
133 typedef struct alias_def_s
*ALIAS_DEF
;
136 char *name
; /* malloced buffer with name, \0, value */
137 const char *value
; /* ptr into name */
140 static int set_opt_arg(ARGPARSE_ARGS
*arg
, unsigned flags
, char *s
);
141 static void show_help(ARGPARSE_OPTS
*opts
, unsigned flags
);
142 static void show_version(void);
145 initialize( ARGPARSE_ARGS
*arg
, const char *filename
, unsigned *lineno
)
147 if( !(arg
->flags
& (1<<15)) ) { /* initialize this instance */
148 arg
->internal
.idx
= 0;
149 arg
->internal
.last
= NULL
;
150 arg
->internal
.inarg
= 0;
151 arg
->internal
.stopped
= 0;
152 arg
->internal
.aliases
= NULL
;
153 arg
->internal
.cur_alias
= NULL
;
155 arg
->flags
|= 1<<15; /* mark initialized */
157 log_bug("Invalid argument for ArgParse\n");
161 if( arg
->err
) { /* last option was erroneous */
164 if( arg
->r_opt
== -6 )
165 log_error("%s:%u: argument not expected\n", filename
, *lineno
);
166 else if( arg
->r_opt
== -5 )
167 log_error("%s:%u: read error\n", filename
, *lineno
);
168 else if( arg
->r_opt
== -4 )
169 log_error("%s:%u: keyword too long\n", filename
, *lineno
);
170 else if( arg
->r_opt
== -3 )
171 log_error("%s:%u: missing argument\n", filename
, *lineno
);
172 else if( arg
->r_opt
== -7 )
173 log_error("%s:%u: invalid command\n", filename
, *lineno
);
174 else if( arg
->r_opt
== -10 )
175 log_error("%s:%u: invalid alias definition\n",filename
,*lineno
);
177 log_error("%s:%u: invalid option\n", filename
, *lineno
);
180 if( arg
->r_opt
== -3 )
181 log_error("Missing argument for option \"%.50s\"\n",
182 arg
->internal
.last
? arg
->internal
.last
:"[??]" );
183 else if( arg
->r_opt
== -6 )
184 log_error("Option \"%.50s\" does not expect an argument\n",
185 arg
->internal
.last
? arg
->internal
.last
:"[??]" );
186 else if( arg
->r_opt
== -7 )
187 log_error("Invalid command \"%.50s\"\n",
188 arg
->internal
.last
? arg
->internal
.last
:"[??]" );
189 else if( arg
->r_opt
== -8 )
190 log_error("Option \"%.50s\" is ambiguous\n",
191 arg
->internal
.last
? arg
->internal
.last
:"[??]" );
192 else if( arg
->r_opt
== -9 )
193 log_error("Command \"%.50s\" is ambiguous\n",
194 arg
->internal
.last
? arg
->internal
.last
:"[??]" );
196 log_error("Invalid option \"%.50s\"\n",
197 arg
->internal
.last
? arg
->internal
.last
:"[??]" );
199 if( arg
->err
!= 1 || arg
->r_opt
== -5 )
204 /* clearout the return value union */
205 arg
->r
.ret_str
= NULL
;
211 store_alias( ARGPARSE_ARGS
*arg
, char *name
, char *value
)
213 /* TODO: replace this dummy function with a rea one
214 * and fix the probelms IRIX has with (ALIAS_DEV)arg..
218 ALIAS_DEF a
= xmalloc( sizeof *a
);
221 a
->next
= (ALIAS_DEF
)arg
->internal
.aliases
;
222 (ALIAS_DEF
)arg
->internal
.aliases
= a
;
227 * Get options from a file.
228 * Lines starting with '#' are comment lines.
229 * Syntax is simply a keyword and the argument.
230 * Valid keywords are all keywords from the long_opt list without
231 * the leading dashes. The special keywords "help", "warranty" and "version"
232 * are not valid here.
233 * The special keyword "alias" may be used to store alias definitions,
234 * which are later expanded like long options.
235 * Caller must free returned strings.
236 * If called with FP set to NULL command line args are parse instead.
238 * Q: Should we allow the syntax
240 * and accept for boolean options a value of 1/0, yes/no or true/false?
241 * Note: Abbreviation of options is here not allowed.
244 optfile_parse( FILE *fp
, const char *filename
, unsigned *lineno
,
245 ARGPARSE_ARGS
*arg
, ARGPARSE_OPTS
*opts
)
255 if( !fp
) /* same as arg_parse() in this case */
256 return arg_parse( arg
, opts
);
258 initialize( arg
, filename
, lineno
);
260 /* find the next keyword */
264 if( c
== '\n' || c
== EOF
) {
269 else if( state
== 2 ) {
271 for(i
=0; opts
[i
].short_opt
; i
++ )
272 if( opts
[i
].long_opt
&& !strcmp( opts
[i
].long_opt
, keyword
) )
275 arg
->r_opt
= opts
[idx
].short_opt
;
276 if( inverse
) /* this does not have an effect, hmmm */
277 arg
->r_opt
= -arg
->r_opt
;
278 if( !opts
[idx
].short_opt
) /* unknown command/option */
279 arg
->r_opt
= (opts
[idx
].flags
& 256)? -7:-2;
280 else if( !(opts
[idx
].flags
& 7) ) /* does not take an arg */
281 arg
->r_type
= 0; /* okay */
282 else if( (opts
[idx
].flags
& 8) ) /* argument is optional */
283 arg
->r_type
= 0; /* okay */
284 else /* required argument */
285 arg
->r_opt
= -3; /* error */
288 else if( state
== 3 ) { /* no argument found */
290 arg
->r_opt
= -3; /* error */
291 else if( !(opts
[idx
].flags
& 7) ) /* does not take an arg */
292 arg
->r_type
= 0; /* okay */
293 else if( (opts
[idx
].flags
& 8) ) /* no optional argument */
294 arg
->r_type
= 0; /* okay */
295 else /* no required argument */
296 arg
->r_opt
= -3; /* error */
299 else if( state
== 4 ) { /* have an argument */
307 p
= strpbrk( buffer
, " \t" );
317 store_alias( arg
, buffer
, p
);
321 else if( !(opts
[idx
].flags
& 7) ) /* does not take an arg */
322 arg
->r_opt
= -6; /* error */
327 buffer
= xstrdup(keyword
);
332 trim_spaces( buffer
);
334 /* remove quotes if they totally enclose the
335 string, and do not occur within the string */
336 if( *p
== '"' && p
[strlen(p
)-1]=='"') {
343 if(*p2
=='"' && *(p2
+1)=='\0') {
348 if( !set_opt_arg(arg
, opts
[idx
].flags
, p
) )
353 else if( c
== EOF
) {
355 arg
->r_opt
= -5; /* read error */
357 arg
->r_opt
= 0; /* eof */
363 else if( state
== -1 )
365 else if( !state
&& isspace(c
) )
366 ; /* skip leading white space */
367 else if( !state
&& c
== '#' )
368 state
= 1; /* start of a comment */
369 else if( state
== 1 )
370 ; /* skip comments */
371 else if( state
== 2 && isspace(c
) ) {
373 for(i
=0; opts
[i
].short_opt
; i
++ )
374 if( opts
[i
].long_opt
&& !strcmp( opts
[i
].long_opt
, keyword
) )
377 arg
->r_opt
= opts
[idx
].short_opt
;
378 if( !opts
[idx
].short_opt
) {
379 if( !strcmp( keyword
, "alias" ) ) {
384 arg
->r_opt
= (opts
[idx
].flags
& 256)? -7:-2;
385 state
= -1; /* skip rest of line and leave */
391 else if( state
== 3 ) { /* skip leading spaces of the argument */
398 else if( state
== 4 ) { /* collect the argument */
404 buffer
= xrealloc(buffer
, buflen
);
408 else if( i
< DIM(keyword
)-1 )
411 buflen
= DIM(keyword
)+50;
412 buffer
= xmalloc(buflen
);
413 memcpy(buffer
, keyword
, i
);
417 else if( i
>= DIM(keyword
)-1 ) {
418 arg
->r_opt
= -4; /* keyword to long */
419 state
= -1; /* skip rest of line and leave */
433 find_long_option( ARGPARSE_ARGS
*arg
,
434 ARGPARSE_OPTS
*opts
, const char *keyword
)
439 /* Would be better if we can do a binary search, but it is not
440 possible to reorder our option table because we would mess
441 up our help strings - What we can do is: Build a nice option
442 lookup table wehn this function is first invoked */
445 for(i
=0; opts
[i
].short_opt
; i
++ )
446 if( opts
[i
].long_opt
&& !strcmp( opts
[i
].long_opt
, keyword
) )
451 /* see whether it is an alias */
452 for( a
= args
->internal
.aliases
; a
; a
= a
->next
) {
453 if( !strcmp( a
->name
, keyword
) ) {
454 /* todo: must parse the alias here */
455 args
->internal
.cur_alias
= a
;
456 return -3; /* alias available */
461 /* not found, see whether it is an abbreviation */
462 /* aliases may not be abbreviated */
463 n
= strlen( keyword
);
464 for(i
=0; opts
[i
].short_opt
; i
++ ) {
465 if( opts
[i
].long_opt
&& !strncmp( opts
[i
].long_opt
, keyword
, n
) ) {
467 for(j
=i
+1; opts
[j
].short_opt
; j
++ ) {
469 && !strncmp( opts
[j
].long_opt
, keyword
, n
) )
470 return -2; /* abbreviation is ambiguous */
479 arg_parse( ARGPARSE_ARGS
*arg
, ARGPARSE_OPTS
*opts
)
487 initialize( arg
, NULL
, NULL
);
490 idx
= arg
->internal
.idx
;
492 if( !idx
&& argc
&& !(arg
->flags
& (1<<4)) ) { /* skip the first entry */
493 argc
--; argv
++; idx
++;
497 if( !argc
) { /* no more args */
499 goto leave
; /* ready */
503 arg
->internal
.last
= s
;
505 if( arg
->internal
.stopped
&& (arg
->flags
& (1<<1)) ) {
506 arg
->r_opt
= -1; /* not an option but a argument */
509 argc
--; argv
++; idx
++; /* set to next one */
511 else if( arg
->internal
.stopped
) { /* ready */
515 else if( *s
== '-' && s
[1] == '-' ) { /* long option */
518 arg
->internal
.inarg
= 0;
519 if( !s
[2] && !(arg
->flags
& (1<<3)) ) { /* stop option processing */
520 arg
->internal
.stopped
= 1;
521 argc
--; argv
++; idx
++;
525 argpos
= strchr( s
+2, '=' );
528 i
= find_long_option( arg
, opts
, s
+2 );
532 if( i
< 0 && !strcmp( "help", s
+2) ) {
533 if( !(arg
->flags
& (1<<6)) ) {
534 show_help(opts
, arg
->flags
);
537 else if( i
< 0 && !strcmp( "version", s
+2) ) {
538 if( !(arg
->flags
& (1<<6)) ) {
543 else if( i
< 0 && !strcmp( "warranty", s
+2) ) {
544 puts( strusage(16) );
547 else if( i
< 0 && !strcmp( "dump-options", s
+2) ) {
548 for(i
=0; opts
[i
].short_opt
; i
++ ) {
549 if( opts
[i
].long_opt
)
550 printf( "--%s\n", opts
[i
].long_opt
);
552 fputs("--dump-options\n--help\n--version\n--warranty\n", stdout
);
556 if( i
== -2 ) /* ambiguous option */
560 arg
->r
.ret_str
= s
+2;
563 arg
->r_opt
= opts
[i
].short_opt
;
566 else if( (opts
[i
].flags
& 7) ) {
574 if( !s2
&& (opts
[i
].flags
& 8) ) { /* no argument but it is okay*/
575 arg
->r_type
= 0; /* because it is optional */
578 arg
->r_opt
= -3; /* missing argument */
580 else if( !argpos
&& *s2
== '-' && (opts
[i
].flags
& 8) ) {
581 /* the argument is optional and the next seems to be
582 * an option. We do not check this possible option
583 * but assume no argument */
587 set_opt_arg(arg
, opts
[i
].flags
, s2
);
589 argc
--; argv
++; idx
++; /* skip one */
593 else { /* does not take an argument */
595 arg
->r_type
= -6; /* argument not expected */
599 argc
--; argv
++; idx
++; /* set to next one */
601 else if( (*s
== '-' && s
[1]) || arg
->internal
.inarg
) { /* short option */
604 if( !arg
->internal
.inarg
) {
605 arg
->internal
.inarg
++;
606 if( arg
->flags
& (1<<5) ) {
607 for(i
=0; opts
[i
].short_opt
; i
++ )
608 if( opts
[i
].long_opt
&& !strcmp( opts
[i
].long_opt
, s
+1)) {
614 s
+= arg
->internal
.inarg
;
617 for(i
=0; opts
[i
].short_opt
; i
++ )
618 if( opts
[i
].short_opt
== *s
)
622 if( !opts
[i
].short_opt
&& ( *s
== 'h' || *s
== '?' ) ) {
623 if( !(arg
->flags
& (1<<6)) ) {
624 show_help(opts
, arg
->flags
);
628 arg
->r_opt
= opts
[i
].short_opt
;
629 if( !opts
[i
].short_opt
) {
630 arg
->r_opt
= (opts
[i
].flags
& 256)? -7:-2;
631 arg
->internal
.inarg
++; /* point to the next arg */
634 else if( (opts
[i
].flags
& 7) ) {
635 if( s
[1] && !dash_kludge
) {
637 set_opt_arg(arg
, opts
[i
].flags
, s2
);
641 if( !s2
&& (opts
[i
].flags
& 8) ) { /* no argument but it is okay*/
642 arg
->r_type
= 0; /* because it is optional */
645 arg
->r_opt
= -3; /* missing argument */
647 else if( *s2
== '-' && s2
[1] && (opts
[i
].flags
& 8) ) {
648 /* the argument is optional and the next seems to be
649 * an option. We do not check this possible option
650 * but assume no argument */
654 set_opt_arg(arg
, opts
[i
].flags
, s2
);
655 argc
--; argv
++; idx
++; /* skip one */
658 s
= "x"; /* so that !s[1] yields false */
660 else { /* does not take an argument */
662 arg
->internal
.inarg
++; /* point to the next arg */
664 if( !s
[1] || dash_kludge
) { /* no more concatenated short options */
665 arg
->internal
.inarg
= 0;
666 argc
--; argv
++; idx
++;
669 else if( arg
->flags
& (1<<2) ) {
670 arg
->r_opt
= -1; /* not an option but a argument */
673 argc
--; argv
++; idx
++; /* set to next one */
676 arg
->internal
.stopped
= 1; /* stop option processing */
683 arg
->internal
.idx
= idx
;
690 set_opt_arg(ARGPARSE_ARGS
*arg
, unsigned flags
, char *s
)
692 int base
= (flags
& 16)? 0 : 10;
694 switch( arg
->r_type
= (flags
& 7) ) {
695 case 1: /* takes int argument */
696 arg
->r
.ret_int
= (int)strtol(s
,NULL
,base
);
698 case 3: /* takes long argument */
699 arg
->r
.ret_long
= strtol(s
,NULL
,base
);
701 case 4: /* takes ulong argument */
702 arg
->r
.ret_ulong
= strtoul(s
,NULL
,base
);
704 case 2: /* takes string argument */
713 long_opt_strlen( ARGPARSE_OPTS
*o
)
715 size_t n
= strlen(o
->long_opt
);
717 if( o
->description
&& *o
->description
== '|' ) {
723 for(; *s
&& *s
!= '|'; s
++ )
730 * Print formatted help. The description string has some special
732 * - A description string which is "@" suppresses help output for
734 * - a description,ine which starts with a '@' and is followed by
735 * any other characters is printed as is; this may be used for examples
737 * - A description which starts with a '|' outputs the string between this
738 * bar and the next one as arguments of the long option.
741 show_help( ARGPARSE_OPTS
*opts
, unsigned flags
)
749 if( opts
[0].description
) { /* auto format the option description */
751 /* get max. length of long options */
752 for(i
=indent
=0; opts
[i
].short_opt
; i
++ ) {
753 if( opts
[i
].long_opt
)
754 if( !opts
[i
].description
|| *opts
[i
].description
!= '@' )
755 if( (j
=long_opt_strlen(opts
+i
)) > indent
&& j
< 35 )
758 /* example: " -v, --verbose Viele Sachen ausgeben" */
760 if( *opts
[0].description
!= '@' )
762 for(i
=0; opts
[i
].short_opt
; i
++ ) {
763 s
= _( opts
[i
].description
);
764 if( s
&& *s
== '@' && !s
[1] ) /* hide this line */
766 if( s
&& *s
== '@' ) { /* unindented comment only line */
780 if( opts
[i
].short_opt
< 256 ) {
781 printf(" -%c", opts
[i
].short_opt
);
782 if( !opts
[i
].long_opt
) {
783 if(s
&& *s
== '|' ) {
785 for(s
++ ; *s
&& *s
!= '|'; s
++, j
++ )
794 if( opts
[i
].long_opt
) {
795 j
+= printf("%c --%s", opts
[i
].short_opt
< 256?',':' ',
797 if(s
&& *s
== '|' ) {
802 for( ; *s
&& *s
!= '|'; s
++, j
++ )
810 for(;j
< indent
; j
++ )
813 if( *s
&& j
> indent
) {
815 for(j
=0;j
< indent
; j
++ )
822 for(j
=0;j
< indent
; j
++ )
833 puts("\n(A single dash may be used instead of the double ones)");
835 if( (s
=strusage(19)) ) { /* bug reports to ... */
849 fputs(strusage(11), stdout
);
850 if( (s
=strusage(12)) )
852 printf(" %s\n", strusage(13) );
853 /* additional version lines */
854 for(i
=20; i
< 30; i
++ )
855 if( (s
=strusage(i
)) )
857 /* copyright string */
858 if( (s
=strusage(14)) )
860 /* copying conditions */
861 if( (s
=strusage(15)) )
864 if( (s
=strusage(18)) )
866 /* additional program info */
867 for(i
=30; i
< 40; i
++ )
868 if( (s
=strusage(i
)) )
869 fputs( (const byte
*)s
, stdout
);
878 fprintf(stderr
,"%s %s; %s\n", strusage(11), strusage(13),
882 else if( level
== 1 ) {
883 fputs(strusage(40),stderr
);
886 else if( level
== 2 ) {
893 * 0: Copyright String auf stderr ausgeben
894 * 1: Kurzusage auf stderr ausgeben und beenden
895 * 2: Langusage auf stdout ausgeben und beenden
896 * 11: name of program
897 * 12: optional name of package which includes this program.
899 * 14: copyright string
900 * 15: Short copying conditions (with LFs)
901 * 16: Long copying conditions (with LFs)
902 * 17: Optional printable OS name
903 * 18: Optional thanks list (with LFs)
904 * 19: Bug report info
905 *20..29: Additional lib version strings.
906 *30..39: Additional program info (with LFs)
907 * 40: short usage note (with LF)
908 * 41: long usage note (with LF)
911 default_strusage( int level
)
913 const char *p
= NULL
;
915 case 11: p
= "foo"; break;
916 case 13: p
= "0.0"; break;
917 case 14: p
= "Copyright (C) 2006 Free Software Foundation, Inc."; break;
919 "This program comes with ABSOLUTELY NO WARRANTY.\n"
920 "This is free software, and you are welcome to redistribute it\n"
921 "under certain conditions. See the file COPYING for details.\n"; break;
923 "This is free software; you can redistribute it and/or modify\n"
924 "it under the terms of the GNU General Public License as published by\n"
925 "the Free Software Foundation; either version 2 of the License, or\n"
926 "(at your option) any later version.\n\n"
927 "It is distributed in the hope that it will be useful,\n"
928 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
929 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
930 "GNU General Public License for more details.\n\n"
931 "You should have received a copy of the GNU General Public License\n"
932 "along with this program; if not, write to the Free Software\n"
933 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n";
935 case 40: /* short and long usage */
936 case 41: p
= ""; break;
956 main(int argc
, char **argv
)
958 ARGPARSE_OPTS opts
[] = {
959 { 'v', "verbose", 0 , "Laut sein"},
960 { 'e', "echo" , 0 , "Zeile ausgeben, damit wir sehen, was wir einegegeben haben"},
961 { 'd', "debug", 0 , "Debug\nfalls mal etasws\nSchief geht"},
962 { 'o', "output", 2 },
963 { 'c', "cross-ref", 2|8, "cross-reference erzeugen\n" },
964 { 'm', "my-option", 1|8 },
965 { 500, "a-long-option", 0 },
967 ARGPARSE_ARGS pargs
= { &argc
, &argv
, 2|4|32 };
970 while( ArgParse( &pargs
, opts
) ) {
971 switch( pargs
.r_opt
) {
972 case -1 : printf( "arg=`%s'\n", pargs
.r
.ret_str
); break;
973 case 'v': opt
.verbose
++; break;
974 case 'e': opt
.echo
++; break;
975 case 'd': opt
.debug
++; break;
976 case 'o': opt
.outfile
= pargs
.r
.ret_str
; break;
977 case 'c': opt
.crf
= pargs
.r_type
? pargs
.r
.ret_str
:"a.crf"; break;
978 case 'm': opt
.myopt
= pargs
.r_type
? pargs
.r
.ret_int
: 1; break;
979 case 500: opt
.a_long_one
++; break;
980 default : pargs
.err
= 1; break; /* force warning output */
983 for(i
=0; i
< argc
; i
++ )
984 printf("%3d -> (%s)\n", i
, argv
[i
] );
987 printf(" verbose=%d\n", opt
.verbose
);
989 printf(" debug=%d\n", opt
.debug
);
991 printf(" outfile=`%s'\n", opt
.outfile
);
993 printf(" crffile=`%s'\n", opt
.crf
);
995 printf(" myopt=%d\n", opt
.myopt
);
997 printf(" a-long-one=%d\n", opt
.a_long_one
);
999 printf(" echo=%d\n", opt
.echo
);
1004 /**** bottom of file ****/