home *** CD-ROM | disk | FTP | other *** search
- /*
- ** GETARGS.C Command line argument processor for C programs
- **
- ** (C) Copyright 1985, Allen I. Holub. All rights reserved.
- ** This program may be copied for personal, non-profit use only.
- **
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <process.h>
- #include <string.h>
-
- #include <local/what.h>
-
- /*
- ** conditional compilation switches
- */
-
- #define CASEBLIND /* if case insensitivity */
- #define MULTIPLE /* if have multiple commands/switch */
-
- #include <local/getargs.h>
-
- /*
- ** prototypes and declarations
- */
-
- extern int stoi( char** );
- extern long stol( char** );
- typedef int (*PFI)();
-
- static char *setarg( ARG *, char * );
- static ARG *findarg( int, ARG *, int );
- #ifndef NOUSAGE
- static void pr_usage( ARG *, int );
- #endif
-
- /*
- ** global data
- */
-
- static char switchar[] = "-/";
-
- /*
- ** "what" strings
- */
-
- static char *WhatStrings[] =
- {
- WHATWHEN,
- WHATDATE,
- WHAT("Copyright (c) 1985, Allen I. Holub"),
- WHAT(" All Rights Reserved")
- };
-
-
- /* .SUBTITLE "setarg - set switch argument value" .EJECT */
- /*
- ** function: setarg
- **
- ** purpose: this function is called by getargs() to process
- ** a switch once it is found. this usually involves
- ** setting the value of an associated variable.
- */
-
- static char *setarg( argp, linep )
-
- ARG *argp;
- char *linep;
-
- {
- char temp;
-
- /*
- ** Set an argument. argp points at the argument table entry
- ** corresponding to *linep. Return linep, updated to point
- ** past the argument being set.
- */
-
- ++linep;
-
- switch( argp->type )
- {
- case INTEGER:
-
- * (int *) argp->variable = stoi( &linep );
- break;
-
- case LONG:
-
- * (long *) argp->variable = stol( &linep );
- break;
-
- case BOOLEAN:
-
- * (int *) argp->variable = 1;
- break;
-
- case CHARACTER:
-
- * (char *) argp->variable = *linep++;
- break;
-
- case UCHARACTER:
-
- temp = *linep++;
- * (char *) argp->variable = toupper( temp );
- break;
-
- case STRING:
-
- * (char **) argp->variable = linep;
- linep = "";
- break;
-
- case PROC:
-
- (* (PFI)(argp->variable) )( linep );
- linep = "";
- break;
-
- default:
-
- fprintf( stderr, "\nsetarg() Internal Error: Bad Argument Type\n" );
- break;
- }
-
- return ( linep );
- }
-
- /* .SUBTITLE "findarg - find switch argument" .EJECT */
- /*
- ** function: findarg
- **
- ** purpose: this function is called by getargs() to scan
- ** the provided switch table for the given switch.
- */
-
- static ARG *findarg( c, tabp, tabsize )
-
- int c, tabsize;
- ARG *tabp;
-
- {
- /*
- ** Return pointer to argument table entry corresponding
- ** to c (or 0 if c isn't in table).
- */
-
- for ( ; --tabsize >= 0; tabp++ )
- #ifdef CASEBLIND
- if ( tolower(tabp->arg) == tolower(c) )
- #else
- if ( tabp->arg == c )
- #endif
- return ( tabp );
-
- return ( 0 );
- }
-
- /* .SUBTITLE "pr_usage - print a usage message" .EJECT */
- /*
- ** function: pr_usage
- **
- ** purpose: this function is called by getargs() if an
- ** unknown switch is encountered. it displays
- ** the entire switch table on stderr.
- */
-
- #ifndef NOUSAGE
-
- static void pr_usage( tabp, tabsize )
-
- ARG *tabp;
- int tabsize;
-
- {
- /*
- ** Print the argtab in the form:
- ** -<arg> <errmsg> (value is <*variable>)
- */
-
- for( ; --tabsize >= 0; tabp++ )
- switch ( tabp->type )
- {
- case INTEGER:
-
- fprintf( stderr, "-%c<num> %-40s (value is ", tabp->arg, tabp->errmsg );
- fprintf( stderr, "%-5d)\n", * (int *) (tabp->variable) );
- break;
-
- case LONG:
-
- fprintf( stderr, "-%c<num> %-40s (value is ", tabp->arg, tabp->errmsg );
- fprintf( stderr, "%-5ld)\n", * (long *) (tabp->variable) );
- break;
-
- case BOOLEAN:
-
- fprintf( stderr,"-%c %-40s (value is ", tabp->arg, tabp->errmsg );
- fprintf( stderr, "%-5s)\n", * (char *) (tabp->variable) ? "TRUE": "FALSE" );
- break;
-
- case CHARACTER:
- case UCHARACTER:
-
- fprintf( stderr, "-%c<c> %-40s (value is ", tabp->arg, tabp->errmsg );
- fprintf( stderr, "%-5c)\n", * (char *) (tabp->variable) );
- break;
-
- case STRING:
-
- fprintf( stderr, "-%c<str> %-40s (value is ", tabp->arg, tabp->errmsg );
- fprintf( stderr, "<%s>)\n", *(char**)tabp->variable );
- break;
-
- case PROC:
-
- fprintf( stderr, "-%c<str> %-40s\n", tabp->arg, tabp->errmsg );
- break;
- }
- }
-
- #endif
-
- /* .SUBTITLE "getargs - process command line switches" .EJECT */
- /*
- ** function: getargs
- **
- ** purpose: getargs is generally called from main() to process
- ** and remove any switches from the command line via
- ** the argv[] array.
- */
-
- int getargs( argc, argv, tabp, tabsize )
-
- int argc, tabsize;
- char **argv;
- ARG *tabp;
-
- {
- /*
- ** Process command line arguments. Stripping all command line
- ** switches out of argv. Return a new argc. If an error is found
- ** exit(1) is called (getargs won't return) and a usage message
- ** is printed showing all arguments in the table.
- */
-
- int nargc;
- char **nargv, *p;
- ARG *argp;
- char lastswitchar;
-
- nargc = 1;
- for ( nargv = ++argv; --argc > 0; argv++ )
- {
- if ( !strchr( switchar, **argv ) )
- {
- *nargv++ = *argv;
- nargc++;
- }
- else
- {
- lastswitchar = **argv;
- p = (*argv) + 1;
-
- #ifdef MULTIPLE
- while ( *p )
- #endif
- if ( argp = findarg( *p, tabp, tabsize ) )
- p = setarg( argp, p );
- else
- {
- #ifdef NOUSAGE
- *--p = lastswitchar;
- *nargv++ = p;
- nargc++;
- p = "";
- #else
- fprintf( stderr, "\nIllegal switch <%c>. Legal arguments are:\n\n", *p );
- pr_usage( tabp, tabsize );
- exit( 1 );
- #endif
- }
- }
- }
-
- return ( nargc );
- }
-
-