/* 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. * * 4/15/86 Added usage arguemnt to getargs() * 3/10/87 DWS changed all "variable" references to "varptr" for T16 */ #include #include "getargs.h" /*----------------------------------------------------------------------*/ extern int stoi ( char** ); typedef int (*PFI)(); /*----------------------------------------------------------------------*/ static char *setarg( argp, linep ) ARG *argp; char *linep; { /* 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 INTVAR: *argp->varptr = stoi( &linep ); break; case BOOLEAN: *argp->varptr = 1; break; case CHARVAR: *argp->varptr = *linep++ ; break; case STRING: *(char **)argp->varptr = linep ; linep = ""; break; case PROC: (* (PFI)(argp->varptr) )( linep ); linep = ""; break; default: fprintf(stderr,"INTERNAL ERROR: BAD ARGUMENT TYPE\n"); break; } return( linep ); } /*----------------------------------------------------------------------*/ 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++ ) if( tabp->arg == c ) return tabp; return 0; } static pr_usage( tabp, tabsize ) ARG *tabp; int tabsize; { /* Print the argtab in the form: * - (value is <*varptr>) */ for(; --tabsize >= 0 ; tabp++ ) { switch( tabp->type ) { case INTVAR: fprintf(stderr, "-%c %-40s (value is ", tabp->arg, tabp->errmsg); fprintf(stderr, "%-5d)\n", *(tabp->varptr) ); break; case BOOLEAN: fprintf(stderr,"-%c %-40s (value is ", tabp->arg, tabp->errmsg); fprintf(stderr, "%-5s)\n", *(tabp->varptr) ? "TRUE": "FALSE"); break; case CHARVAR: fprintf(stderr, "-%c %-40s (value is ", tabp->arg, tabp->errmsg); fprintf(stderr, "%-5c <%3x>x)\n", *(tabp->varptr), *(tabp->varptr) ); break; case STRING: fprintf(stderr, "-%c %-40s (value is ", tabp->arg, tabp->errmsg); fprintf(stderr, "<%s>)\n", *(char **)tabp->varptr); break; case PROC: fprintf(stderr, "-%c %-40s\n", tabp->arg, tabp->errmsg); break; } } exit(1); } #define ERRMSG "Illegal argument <%c>. Legal arguments are:\n\n" int getargs( argc, argv, tabp, tabsize, usage ) int argc, tabsize ; char **argv ; ARG *tabp ; int (*usage)(); { /* 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. */ register int nargc ; register char **nargv, *p ; register ARG *argp ; nargc = 1 ; for(nargv = ++argv ; --argc > 0 ; argv++ ) { if( **argv != SWITCHAR ) { *nargv++ = *argv ; nargc++; } else { p = (*argv) + 1 ; while( *p ) { if(argp = findarg(*p, tabp, tabsize)) p = setarg( argp, p ); else { fprintf(stderr, ERRMSG, *p ); pr_usage( tabp, tabsize ); (*usage)(); } } } } return nargc ; }