home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1996 September
/
Simtel-MSDOS-Sep1996-CD2.iso
/
disc2
/
c
/
getargs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1985-09-15
|
4KB
|
149 lines
/* getargs - 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
history...
May 1985 published in Dr. Dobb's Journal #103.
19 May 85 Transcribed by James R. Van Zandt */
#include <stdio.h>
#include <getargs.h>
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. Returns linep, updated to point
past the argument being set */
++linep;
switch(argp->type)
{case INTEGER: *argp->variable=stoi(&linep); break;
case BOOLEAN: *argp->variable=1; break;
case CHARACTER: *argp->variable=*linep++; break;
case STRING: *(char **)argp->variable=linep; linep=""; break;
case PROC: (*(PFI)(argp->variable))(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:
-<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",*(tabp->variable));
break;
case BOOLEAN:
fprintf(stderr,"-%c %-40s (value is ",
tabp->arg, tabp->errmsg);
fprintf(stderr,"%-5s)\n",*(tabp->variable)
?"TRUE":"FALSE");
break;
case CHARACTER:
fprintf(stderr,"-%c<c> %-40s (value is ",
tabp->arg,tabp->errmsg);
fprintf(stderr,"%-5c)\n",*(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;
}
}
}
#define ERRMSG "Illegal argument \'%c\'. Legal arguments are:\n\n"
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. */
register int nargc;
register char **nargv, *p;
register ARG *argp;
nargc=1;
for (nargv=++argv; --argc>0; argv++)
{if(**argv!='-') {*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);
exit(1);
}
}
}
}
return nargc;
}
#define islower(c) ('a'<=(c)&&(c)<='z')
#define toupper(c) (islower(c)?(c)-('a'-'A'):(c))
int stoi(instr) register char **instr;
{ /* Convert string to integer. If string starts with 0x it is
interpreted as a hex number, else if it starts with a 0 it
is octal, else it is decimal. Conversion stops on encountering
the first character which is not a digit in the indicated
radix. *instr is updated to point past the end of the number. */
register int num=0;
register char *str;
int sign=1;
str=*instr;
while(*str==' ' || *str=='\t' || *str=='\n') {str++;}
if(*str=='-') {sign=-1; str++;}
if(*str=='0')
{++str;
if(*str=='x' || *str=='X')
{str++;
while( ('0'<=*str && *str<='9') ||
('a'<=*str && *str<='f') ||
('A'<=*str && *str<='F') )
{num=num*16+
(('0'<=*str && *str<='9') ?
*str-'0' :
toupper(*str)-'A'+10);
str++;
}
}
else {while('0'<=*str && *str<='7') {num = num*8+ *str++ - '0';}}
}
else {while('0'<=*str && *str<='9') {num=num*10+ *str++-'0';}}
*instr=str;
return (num*sign);
}