diff options
Diffstat (limited to 'util/argparse.c')
-rw-r--r-- | util/argparse.c | 996 |
1 files changed, 0 insertions, 996 deletions
diff --git a/util/argparse.c b/util/argparse.c deleted file mode 100644 index ba51980a9..000000000 --- a/util/argparse.c +++ /dev/null @@ -1,996 +0,0 @@ -/* [argparse.c wk 17.06.97] Argument Parser for option handling - * Copyright (C) 1998,1999 Free Software Foundation, Inc. - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> - -#include "libutil-config.h" -#include "mischelp.h" -#include "stringhelp.h" -#ifndef LIBUTIL_CONFIG_OF_GNUPG - #include "logging.h" /* currently not used in GnUPG */ -#endif -#include "argparse.h" - - -/********************************* - * @Summary arg_parse - * #include <wk/lib.h> - * - * typedef struct { - * char *argc; pointer to argc (value subject to change) - * char ***argv; pointer to argv (value subject to change) - * unsigned flags; Global flags (DO NOT CHANGE) - * int err; print error about last option - * 1 = warning, 2 = abort - * int r_opt; return option - * int r_type; type of return value (0 = no argument found) - * union { - * int ret_int; - * long ret_long - * ulong ret_ulong; - * char *ret_str; - * } r; Return values - * struct { - * int idx; - * const char *last; - * void *aliases; - * } internal; DO NOT CHANGE - * } ARGPARSE_ARGS; - * - * typedef struct { - * int short_opt; - * const char *long_opt; - * unsigned flags; - * } ARGPARSE_OPTS; - * - * int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts ); - * - * @Description - * This is my replacement for getopt(). See the example for a typical usage. - * Global flags are: - * Bit 0 : Do not remove options form argv - * Bit 1 : Do not stop at last option but return other args - * with r_opt set to -1. - * Bit 2 : Assume options and real args are mixed. - * Bit 3 : Do not use -- to stop option processing. - * Bit 4 : Do not skip the first arg. - * Bit 5 : allow usage of long option with only one dash - * Bit 6 : ignore --version - * all other bits must be set to zero, this value is modified by the - * function, so assume this is write only. - * Local flags (for each option): - * Bit 2-0 : 0 = does not take an argument - * 1 = takes int argument - * 2 = takes string argument - * 3 = takes long argument - * 4 = takes ulong argument - * Bit 3 : argument is optional (r_type will the be set to 0) - * Bit 4 : allow 0x etc. prefixed values. - * Bit 7 : this is a command and not an option - * You stop the option processing by setting opts to NULL, the function will - * then return 0. - * @Return Value - * Returns the args.r_opt or 0 if ready - * r_opt may be -2/-7 to indicate an unknown option/command. - * @See Also - * ArgExpand - * @Notes - * You do not need to process the options 'h', '--help' or '--version' - * because this function includes standard help processing; but if you - * specify '-h', '--help' or '--version' you have to do it yourself. - * The option '--' stops argument processing; if bit 1 is set the function - * continues to return normal arguments. - * To process float args or unsigned args you must use a string args and do - * the conversion yourself. - * @Example - * - * ARGPARSE_OPTS opts[] = { - * { 'v', "verbose", 0 }, - * { 'd', "debug", 0 }, - * { 'o', "output", 2 }, - * { 'c', "cross-ref", 2|8 }, - * { 'm', "my-option", 1|8 }, - * { 500, "have-no-short-option-for-this-long-option", 0 }, - * {0} }; - * ARGPARSE_ARGS pargs = { &argc, &argv, 0 } - * - * while( ArgParse( &pargs, &opts) ) { - * switch( pargs.r_opt ) { - * case 'v': opt.verbose++; break; - * case 'd': opt.debug++; break; - * case 'o': opt.outfile = pargs.r.ret_str; break; - * case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; - * case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; - * case 500: opt.a_long_one++; break - * default : pargs.err = 1; break; -- force warning output -- - * } - * } - * if( argc > 1 ) - * log_fatal( "Too many args"); - * - */ - -typedef struct alias_def_s *ALIAS_DEF; -struct alias_def_s { - ALIAS_DEF next; - char *name; /* malloced buffer with name, \0, value */ - const char *value; /* ptr into name */ -}; - -static const char *(*strusage_handler)( int ) = NULL; - -static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s); -static void show_help(ARGPARSE_OPTS *opts, unsigned flags); -static void show_version(void); - - -static void -initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) -{ - if( !(arg->flags & (1<<15)) ) { /* initialize this instance */ - arg->internal.idx = 0; - arg->internal.last = NULL; - arg->internal.inarg = 0; - arg->internal.stopped = 0; - arg->internal.aliases = NULL; - arg->internal.cur_alias = NULL; - arg->err = 0; - arg->flags |= 1<<15; /* mark initialized */ - if( *arg->argc < 0 ) - libutil_log_bug("Invalid argument for ArgParse\n"); - } - - - if( arg->err ) { /* last option was erroneous */ - const char *s; - - if( filename ) { - if( arg->r_opt == -6 ) - s = "%s:%u: argument not expected\n"; - else if( arg->r_opt == -5 ) - s = "%s:%u: read error\n"; - else if( arg->r_opt == -4 ) - s = "%s:%u: keyword too long\n"; - else if( arg->r_opt == -3 ) - s = "%s:%u: missing argument\n"; - else if( arg->r_opt == -7 ) - s = "%s:%u: invalid command\n"; - else if( arg->r_opt == -10 ) - s = "%s:%u: invalid alias definition\n"; - else - s = "%s:%u: invalid option\n"; - libutil_log_error(s, filename, *lineno ); - } - else { - if( arg->r_opt == -3 ) - s = "Missing argument for option \"%.50s\"\n"; - else if( arg->r_opt == -6 ) - s = "Option \"%.50s\" does not expect an argument\n"; - else if( arg->r_opt == -7 ) - s = "Invalid command \"%.50s\"\n"; - else if( arg->r_opt == -8 ) - s = "Option \"%.50s\" is ambiguous\n"; - else if( arg->r_opt == -9 ) - s = "Command \"%.50s\" is ambiguous\n"; - else - s = "Invalid option \"%.50s\"\n"; - libutil_log_error(s, arg->internal.last? arg->internal.last:"[??]" ); - } - if( arg->err != 1 ) - exit(2); - arg->err = 0; - } - - /* clearout the return value union */ - arg->r.ret_str = NULL; - arg->r.ret_long= 0; -} - - -static void -store_alias( ARGPARSE_ARGS *arg, char *name, char *value ) -{ - /* TODO: replace this dummy function with a rea one - * and fix the probelms IRIX has with (ALIAS_DEV)arg.. - * used as lvalue - */ -#if 0 - ALIAS_DEF a = m_alloc( sizeof *a ); - a->name = name; - a->value = value; - a->next = (ALIAS_DEF)arg->internal.aliases; - (ALIAS_DEF)arg->internal.aliases = a; -#endif -} - -/**************** - * Get options from a file. - * Lines starting with '#' are comment lines. - * Syntax is simply a keyword and the argument. - * Valid keywords are all keywords from the long_opt list without - * the leading dashes. The special keywords "help", "warranty" and "version" - * are not valid here. - * The special keyword "alias" may be used to store alias definitions, - * which are later expanded like long options. - * Caller must free returned strings. - * If called with FP set to NULL command line args are parse instead. - * - * Q: Should we allow the syntax - * keyword = value - * and accept for boolean options a value of 1/0, yes/no or true/false? - * Note: Abbreviation of options is here not allowed. - */ -int -optfile_parse( FILE *fp, const char *filename, unsigned *lineno, - ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) -{ - int state, i, c; - int idx=0; - char keyword[100]; - char *buffer = NULL; - size_t buflen = 0; - int inverse=0; - int in_alias=0; - - if( !fp ) /* same as arg_parse() in this case */ - return arg_parse( arg, opts ); - - initialize( arg, filename, lineno ); - - /* find the next keyword */ - state = i = 0; - for(;;) { - c=getc(fp); - if( c == '\n' || c== EOF ) { - if( c != EOF ) - ++*lineno; - if( state == -1 ) - break; - else if( state == 2 ) { - keyword[i] = 0; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - break; - idx = i; - arg->r_opt = opts[idx].short_opt; - if( inverse ) /* this does not have an effect, hmmm */ - arg->r_opt = -arg->r_opt; - if( !opts[idx].short_opt ) /* unknown command/option */ - arg->r_opt = (opts[idx].flags & 256)? -7:-2; - else if( (opts[idx].flags & 8) ) /* no argument */ - arg->r_opt = -3; /* error */ - else /* no or optional argument */ - arg->r_type = 0; /* okay */ - break; - } - else if( state == 3 ) { /* no argument found */ - if( in_alias ) - arg->r_opt = -3; /* error */ - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_type = 0; /* okay */ - else if( (opts[idx].flags & 8) ) /* no optional argument */ - arg->r_type = 0; /* okay */ - else /* no required argument */ - arg->r_opt = -3; /* error */ - break; - } - else if( state == 4 ) { /* have an argument */ - if( in_alias ) { - if( !buffer ) - arg->r_opt = -6; - else { - char *p; - - buffer[i] = 0; - p = strpbrk( buffer, " \t" ); - if( p ) { - *p++ = 0; - trim_spaces( p ); - } - if( !p || !*p ) { - libutil_free( buffer ); - arg->r_opt = -10; - } - else { - store_alias( arg, buffer, p ); - } - } - } - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_opt = -6; /* error */ - else { - char *p; - if( !buffer ) { - keyword[i] = 0; - buffer = libutil_strdup(keyword); - } - else - buffer[i] = 0; - - trim_spaces( buffer ); - p = buffer; - if( *p == '"' ) { /* remove quotes */ - p++; - if( *p && p[strlen(p)-1] == '"' ) - p[strlen(p)-1] = 0; - } - if( !set_opt_arg(arg, opts[idx].flags, p) ) - libutil_free(buffer); - } - break; - } - else if( c == EOF ) { - if( ferror(fp) ) - arg->r_opt = -5; /* read error */ - else - arg->r_opt = 0; /* eof */ - break; - } - state = 0; - i = 0; - } - else if( state == -1 ) - ; /* skip */ - else if( !state && isspace(c) ) - ; /* skip leading white space */ - else if( !state && c == '#' ) - state = 1; /* start of a comment */ - else if( state == 1 ) - ; /* skip comments */ - else if( state == 2 && isspace(c) ) { - keyword[i] = 0; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - break; - idx = i; - arg->r_opt = opts[idx].short_opt; - if( !opts[idx].short_opt ) { - if( !strcmp( keyword, "alias" ) ) { - in_alias = 1; - state = 3; - } - else { - arg->r_opt = (opts[idx].flags & 256)? -7:-2; - state = -1; /* skip rest of line and leave */ - } - } - else - state = 3; - } - else if( state == 3 ) { /* skip leading spaces of the argument */ - if( !isspace(c) ) { - i = 0; - keyword[i++] = c; - state = 4; - } - } - else if( state == 4 ) { /* collect the argument */ - if( buffer ) { - if( i < buflen-1 ) - buffer[i++] = c; - else { - buflen += 50; - buffer = libutil_realloc(buffer, buflen); - buffer[i++] = c; - } - } - else if( i < DIM(keyword)-1 ) - keyword[i++] = c; - else { - buflen = DIM(keyword)+50; - buffer = libutil_xmalloc(buflen); - memcpy(buffer, keyword, i); - buffer[i++] = c; - } - } - else if( i >= DIM(keyword)-1 ) { - arg->r_opt = -4; /* keyword to long */ - state = -1; /* skip rest of line and leave */ - } - else { - keyword[i++] = c; - state = 2; - } - } - - return arg->r_opt; -} - - - -static int -find_long_option( ARGPARSE_ARGS *arg, - ARGPARSE_OPTS *opts, const char *keyword ) -{ - int i; - size_t n; - - /* Would be better if we can do a binary search, but it is not - possible to reorder our option table because we would mess - up our help strings - What we can do is: Build a nice option - lookup table wehn this function is first invoked */ - if( !*keyword ) - return -1; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - return i; - #if 0 - { - ALIAS_DEF a; - /* see whether it is an alias */ - for( a = args->internal.aliases; a; a = a->next ) { - if( !strcmp( a->name, keyword) ) { - /* todo: must parse the alias here */ - args->internal.cur_alias = a; - return -3; /* alias available */ - } - } - } - #endif - /* not found, see whether it is an abbreviation */ - /* aliases may not be abbreviated */ - n = strlen( keyword ); - for(i=0; opts[i].short_opt; i++ ) { - if( opts[i].long_opt && !strncmp( opts[i].long_opt, keyword, n ) ) { - int j; - for(j=i+1; opts[j].short_opt; j++ ) { - if( opts[j].long_opt - && !strncmp( opts[j].long_opt, keyword, n ) ) - return -2; /* abbreviation is ambiguous */ - } - return i; - } - } - return -1; -} - -int -arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) -{ - int idx; - int argc; - char **argv; - char *s, *s2; - int i; - - initialize( arg, NULL, NULL ); - argc = *arg->argc; - argv = *arg->argv; - idx = arg->internal.idx; - - if( !idx && argc && !(arg->flags & (1<<4)) ) { /* skip the first entry */ - argc--; argv++; idx++; - } - - next_one: - if( !argc ) { /* no more args */ - arg->r_opt = 0; - goto leave; /* ready */ - } - - s = *argv; - arg->internal.last = s; - - if( arg->internal.stopped && (arg->flags & (1<<1)) ) { - arg->r_opt = -1; /* not an option but a argument */ - arg->r_type = 2; - arg->r.ret_str = s; - argc--; argv++; idx++; /* set to next one */ - } - else if( arg->internal.stopped ) { /* ready */ - arg->r_opt = 0; - goto leave; - } - else if( *s == '-' && s[1] == '-' ) { /* long option */ - char *argpos; - - arg->internal.inarg = 0; - if( !s[2] && !(arg->flags & (1<<3)) ) { /* stop option processing */ - arg->internal.stopped = 1; - argc--; argv++; idx++; - goto next_one; - } - - argpos = strchr( s+2, '=' ); - if( argpos ) - *argpos = 0; - i = find_long_option( arg, opts, s+2 ); - if( argpos ) - *argpos = '='; - - if( i < 0 && !strcmp( "help", s+2) ) - show_help(opts, arg->flags); - else if( i < 0 && !strcmp( "version", s+2) ) { - if( !(arg->flags & (1<<6)) ) { - show_version(); - exit(0); - } - } - else if( i < 0 && !strcmp( "warranty", s+2) ) { - puts( strusage(16) ); - exit(0); - } - else if( i < 0 && !strcmp( "dump-options", s+2) ) { - for(i=0; opts[i].short_opt; i++ ) { - if( opts[i].long_opt ) - printf( "--%s\n", opts[i].long_opt ); - } - fputs("--dump-options\n--help\n--version\n--warranty\n", stdout ); - exit(0); - } - - if( i == -2 ) /* ambiguous option */ - arg->r_opt = -8; - else if( i == -1 ) { - arg->r_opt = -2; - arg->r.ret_str = s+2; - } - else - arg->r_opt = opts[i].short_opt; - if( i < 0 ) - ; - else if( (opts[i].flags & 7) ) { - if( argpos ) { - s2 = argpos+1; - if( !*s2 ) - s2 = NULL; - } - else - s2 = argv[1]; - if( !s2 && (opts[i].flags & 8) ) { /* no argument but it is okay*/ - arg->r_type = 0; /* because it is optional */ - } - else if( !s2 ) { - arg->r_opt = -3; /* missing argument */ - } - else if( !argpos && *s2 == '-' && (opts[i].flags & 8) ) { - /* the argument is optional and the next seems to be - * an option. We do not check this possible option - * but assume no argument */ - arg->r_type = 0; - } - else { - set_opt_arg(arg, opts[i].flags, s2); - if( !argpos ) { - argc--; argv++; idx++; /* skip one */ - } - } - } - else { /* does not take an argument */ - if( argpos ) - arg->r_type = -6; /* argument not expected */ - else - arg->r_type = 0; - } - argc--; argv++; idx++; /* set to next one */ - } - else if( (*s == '-' && s[1]) || arg->internal.inarg ) { /* short option */ - int dash_kludge = 0; - i = 0; - if( !arg->internal.inarg ) { - arg->internal.inarg++; - if( arg->flags & (1<<5) ) { - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, s+1)) { - dash_kludge=1; - break; - } - } - } - s += arg->internal.inarg; - - if( !dash_kludge ) { - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].short_opt == *s ) - break; - } - - if( !opts[i].short_opt && ( *s == 'h' || *s == '?' ) ) - show_help(opts, arg->flags); - - arg->r_opt = opts[i].short_opt; - if( !opts[i].short_opt ) { - arg->r_opt = (opts[i].flags & 256)? -7:-2; - arg->internal.inarg++; /* point to the next arg */ - arg->r.ret_str = s; - } - else if( (opts[i].flags & 7) ) { - if( s[1] && !dash_kludge ) { - s2 = s+1; - set_opt_arg(arg, opts[i].flags, s2); - } - else { - s2 = argv[1]; - if( !s2 && (opts[i].flags & 8) ) { /* no argument but it is okay*/ - arg->r_type = 0; /* because it is optional */ - } - else if( !s2 ) { - arg->r_opt = -3; /* missing argument */ - } - else if( *s2 == '-' && s2[1] && (opts[i].flags & 8) ) { - /* the argument is optional and the next seems to be - * an option. We do not check this possible option - * but assume no argument */ - arg->r_type = 0; - } - else { - set_opt_arg(arg, opts[i].flags, s2); - argc--; argv++; idx++; /* skip one */ - } - } - s = "x"; /* so that !s[1] yields false */ - } - else { /* does not take an argument */ - arg->r_type = 0; - arg->internal.inarg++; /* point to the next arg */ - } - if( !s[1] || dash_kludge ) { /* no more concatenated short options */ - arg->internal.inarg = 0; - argc--; argv++; idx++; - } - } - else if( arg->flags & (1<<2) ) { - arg->r_opt = -1; /* not an option but a argument */ - arg->r_type = 2; - arg->r.ret_str = s; - argc--; argv++; idx++; /* set to next one */ - } - else { - arg->internal.stopped = 1; /* stop option processing */ - goto next_one; - } - - leave: - *arg->argc = argc; - *arg->argv = argv; - arg->internal.idx = idx; - return arg->r_opt; -} - - - -static int -set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s) -{ - int base = (flags & 16)? 0 : 10; - - switch( arg->r_type = (flags & 7) ) { - case 1: /* takes int argument */ - arg->r.ret_int = (int)strtol(s,NULL,base); - return 0; - case 3: /* takes long argument */ - arg->r.ret_long= strtol(s,NULL,base); - return 0; - case 4: /* takes ulong argument */ - arg->r.ret_ulong= strtoul(s,NULL,base); - return 0; - case 2: /* takes string argument */ - default: - arg->r.ret_str = s; - return 1; - } -} - - -static size_t -long_opt_strlen( ARGPARSE_OPTS *o ) -{ - size_t n = strlen(o->long_opt); - - if( o->description && *o->description == '|' ) { - const char *s; - - s=o->description+1; - if( *s != '=' ) - n++; - for(; *s && *s != '|'; s++ ) - n++; - } - return n; -} - -/**************** - * Print formatted help. The description string has some special - * meanings: - * - A description string which is "@" suppresses help output for - * this option - * - a description,ine which starts with a '@' and is followed by - * any other characters is printed as is; this may be used for examples - * ans such. - * - A description which starts with a '|' outputs the string between this - * bar and the next one as arguments of the long option. - */ -static void -show_help( ARGPARSE_OPTS *opts, unsigned flags ) -{ - const char *s; - - show_version(); - putchar('\n'); - s = strusage(41); - puts(s); - if( opts[0].description ) { /* auto format the option description */ - int i,j, indent; - /* get max. length of long options */ - for(i=indent=0; opts[i].short_opt; i++ ) { - if( opts[i].long_opt ) - if( !opts[i].description || *opts[i].description != '@' ) - if( (j=long_opt_strlen(opts+i)) > indent && j < 35 ) - indent = j; - } - /* example: " -v, --verbose Viele Sachen ausgeben" */ - indent += 10; - if( *opts[0].description != '@' ) - puts("Options:"); - for(i=0; opts[i].short_opt; i++ ) { - s = _( opts[i].description ); - if( s && *s== '@' && !s[1] ) /* hide this line */ - continue; - if( s && *s == '@' ) { /* unindented comment only line */ - for(s++; *s; s++ ) { - if( *s == '\n' ) { - if( s[1] ) - putchar('\n'); - } - else - putchar(*s); - } - putchar('\n'); - continue; - } - - j = 3; - if( opts[i].short_opt < 256 ) { - printf(" -%c", opts[i].short_opt ); - if( !opts[i].long_opt ) { - if(s && *s == '|' ) { - putchar(' '); j++; - for(s++ ; *s && *s != '|'; s++, j++ ) - putchar(*s); - if( *s ) - s++; - } - } - } - else - fputs(" ", stdout); - if( opts[i].long_opt ) { - j += printf("%c --%s", opts[i].short_opt < 256?',':' ', - opts[i].long_opt ); - if(s && *s == '|' ) { - if( *++s != '=' ) { - putchar(' '); - j++; - } - for( ; *s && *s != '|'; s++, j++ ) - putchar(*s); - if( *s ) - s++; - } - fputs(" ", stdout); - j += 3; - } - for(;j < indent; j++ ) - putchar(' '); - if( s ) { - if( *s && j > indent ) { - putchar('\n'); - for(j=0;j < indent; j++ ) - putchar(' '); - } - for(; *s; s++ ) { - if( *s == '\n' ) { - if( s[1] ) { - putchar('\n'); - for(j=0;j < indent; j++ ) - putchar(' '); - } - } - else - putchar(*s); - } - } - putchar('\n'); - } - if( flags & 32 ) - puts("\n(A single dash may be used instead of the double ones)"); - } - if( (s=strusage(19)) ) { /* bug reports to ... */ - putchar('\n'); - fputs(s, stdout); - } - fflush(stdout); - exit(0); -} - -static void -show_version() -{ - const char *s; - int i; - /* version line */ - fputs(strusage(11), stdout); - if( (s=strusage(12)) ) - printf(" (%s)", s ); - printf(" %s\n", strusage(13) ); - /* additional version lines */ - for(i=20; i < 30; i++ ) - if( (s=strusage(i)) ) - printf("%s\n", s ); - /* copyright string */ - if( (s=strusage(14)) ) - printf("%s\n", s ); - /* copying conditions */ - if( (s=strusage(15)) ) - fputs(s, stdout); - /* thanks */ - if( (s=strusage(18)) ) - fputs(s, stdout); - /* additional program info */ - for(i=30; i < 40; i++ ) - if( (s=strusage(i)) ) - fputs( (const byte*)s, stdout); - fflush(stdout); -} - - -void -usage( int level ) -{ - if( !level ) { - fprintf(stderr,"%s %s; %s\n", strusage(11), strusage(13), - strusage(14) ); - fflush(stderr); - } - else if( level == 1 ) { - fputs(strusage(40),stderr); - exit(2); - } - else if( level == 2 ) { - puts(strusage(41)); - exit(0); - } -} - -/* Level - * 0: Copyright String auf stderr ausgeben - * 1: Kurzusage auf stderr ausgeben und beenden - * 2: Langusage auf stdout ausgeben und beenden - * 11: name of program - * 12: optional name of package which includes this program. - * 13: version string - * 14: copyright string - * 15: Short copying conditions (with LFs) - * 16: Long copying conditions (with LFs) - * 17: Optional printable OS name - * 18: Optional thanks list (with LFs) - * 19: Bug report info - *20..29: Additional lib version strings. - *30..39: Additional program info (with LFs) - * 40: short usage note (with LF) - * 41: long usage note (with LF) - */ -const char * -strusage( int level ) -{ - const char *p = strusage_handler? strusage_handler(level) : NULL; - - if( p ) - return p; - - switch( level ) { - case 11: p = "foo"; break; - case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 1999 Free Software Foundation, Inc."; break; - case 15: p = -"This program comes with ABSOLUTELY NO WARRANTY.\n" -"This is free software, and you are welcome to redistribute it\n" -"under certain conditions. See the file COPYING for details.\n"; break; - case 16: p = -"This is free software; you can redistribute it and/or modify\n" -"it under the terms of the GNU General Public License as published by\n" -"the Free Software Foundation; either version 2 of the License, or\n" -"(at your option) any later version.\n\n" -"It is distributed in the hope that it will be useful,\n" -"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" -"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" -"GNU General Public License for more details.\n\n" -"You should have received a copy of the GNU General Public License\n" -"along with this program; if not, write to the Free Software\n" -"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"; - break; - case 40: /* short and long usage */ - case 41: p = ""; break; - } - - return p; -} - -void -set_strusage( const char *(*f)( int ) ) -{ - strusage_handler = f; -} - - -#ifdef TEST -static struct { - int verbose; - int debug; - char *outfile; - char *crf; - int myopt; - int echo; - int a_long_one; -}opt; - -int -main(int argc, char **argv) -{ - ARGPARSE_OPTS opts[] = { - { 'v', "verbose", 0 , "Laut sein"}, - { 'e', "echo" , 0 , "Zeile ausgeben, damit wir sehen, was wir einegegeben haben"}, - { 'd', "debug", 0 , "Debug\nfalls mal etasws\nSchief geht"}, - { 'o', "output", 2 }, - { 'c', "cross-ref", 2|8, "cross-reference erzeugen\n" }, - { 'm', "my-option", 1|8 }, - { 500, "a-long-option", 0 }, - {0} }; - ARGPARSE_ARGS pargs = { &argc, &argv, 2|4|32 }; - int i; - - while( ArgParse( &pargs, opts) ) { - switch( pargs.r_opt ) { - case -1 : printf( "arg=`%s'\n", pargs.r.ret_str); break; - case 'v': opt.verbose++; break; - case 'e': opt.echo++; break; - case 'd': opt.debug++; break; - case 'o': opt.outfile = pargs.r.ret_str; break; - case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break; - case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break; - case 500: opt.a_long_one++; break; - default : pargs.err = 1; break; /* force warning output */ - } - } - for(i=0; i < argc; i++ ) - printf("%3d -> (%s)\n", i, argv[i] ); - puts("Options:"); - if( opt.verbose ) - printf(" verbose=%d\n", opt.verbose ); - if( opt.debug ) - printf(" debug=%d\n", opt.debug ); - if( opt.outfile ) - printf(" outfile=`%s'\n", opt.outfile ); - if( opt.crf ) - printf(" crffile=`%s'\n", opt.crf ); - if( opt.myopt ) - printf(" myopt=%d\n", opt.myopt ); - if( opt.a_long_one ) - printf(" a-long-one=%d\n", opt.a_long_one ); - if( opt.echo ) - printf(" echo=%d\n", opt.echo ); - return 0; -} -#endif - -/**** bottom of file ****/ |