home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
msdos
/
sysutl
/
idt.arc
/
GETARGS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-06-11
|
6KB
|
292 lines
/*
** 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 );
}