home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_progs
/
educ
/
listplot.lzh
/
LISTPLOT
/
CSRC
/
GET_ARGS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-15
|
15KB
|
774 lines
/*
* get_args.c
*
* command line argument parser
*/
#include <stdio.h>
#include <errno.h>
extern int errno;
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include "datatypes.h"
/*
#define min(A,B) A<B? A : B
#define max(A,B) A>B? A : B
*/
void
get_args(argc, argv, Symbols, Usage, Function)
int argc;
char **argv;
ARGDEF *Symbols[];
char *Usage[], *Function[];
{
register int i;
bool helped;
bool Help(), ParseHelp();
/* set default values */
SetDefaults(Symbols);
helped = FALSE;
for (i=1; i<argc; i++)
if (argv[i][0] == '?' || argv[i][0] == '-') {
Help(Usage, Function, Symbols, "All");
helped = TRUE;
} else if (strncmp(argv[i], "Help",4)==0 || strncmp(argv[i],"help",4)==0) {
ParseHelp(Usage, Function, Symbols, argv[i]);
helped = TRUE;
} else if (ParseArg(Symbols, argv[i])) {
continue;
} else {
errno = EINVAL;
perror(argv[i]);
goto error_exit;
}
if (helped == TRUE)
exit(0);
else
return;
error_exit:
PrintUsage(stderr, Usage, Function, Symbols);
exit(errno);
}
void
SetDefaults(Symbols)
ARGDEF *Symbols[];
{
register int i;
for (i=0; Symbols[i]; i++)
if (SetValue(
Symbols[i]->ad_value,
Symbols[i]->ad_default,
Symbols[i]->ad_defaultType
) != TRUE) {
/* error */
fprintf(stderr,"Internal error: (SetDefaults) Unable to set ");
PrintArgDef(stderr,Symbols[i]);
errno = EINVAL;
exit(errno);
}
return;
}
bool
SetValue(Val, ValStr, ValType)
VALUE *Val;
char *ValStr;
char *ValType;
{
register int WidType;
WidType = strlen(ValType);
if (strncmp(ValType, "string", WidType) == 0) {
return(SetString(Val, ValStr));
} else if (strncmp(ValType, "dbl", WidType) == 0) {
return(SetDbl(Val, ValStr));
} else if (strncmp(ValType, "float", WidType) == 0) {
return(SetFloat(Val, ValStr));
} else if (strncmp(ValType, "int", WidType) == 0) {
return(SetInt(Val, ValStr));
} else if (strncmp(ValType, "boolean", WidType) == 0) {
return(SetBool(Val, ValStr));
} else if (strncmp(ValType, "byte", WidType) == 0) {
return(SetByte(Val, ValStr));
} else if (strncmp(ValType, "interval", WidType) == 0) {
return(SetInterval(Val, ValStr));
} else if (strncmp(ValType, "set", min(WidType,3)) == 0) {
return(SetSet(Val, ValStr, ValType, WidType));
} else if (strncmp(ValType, "rect", WidType) == 0) {
return(SetRect(Val, ValStr));
} else {
return(FALSE);
}
}
bool
SetString(Val, ValStr)
VALUE *Val;
char *ValStr;
{
Val->val_type = string;
Val->val_u.udt_string = StrDup(ValStr);
return(TRUE);
}
bool
SetDbl(Val, ValStr)
VALUE *Val;
char *ValStr;
{
double D;
if (sscanf(ValStr, "%lf", &D) == 1) {
Val->val_type = dbl;
Val->val_u.udt_dbl = D;
return(TRUE);
} else {
return(FALSE);
}
}
bool
SetFloat(Val, ValStr)
VALUE *Val;
char *ValStr;
{
float F;
if (sscanf(ValStr, "%f", &F) == 1) {
Val->val_type = flt;
Val->val_u.udt_flt = F;
return(TRUE);
} else {
return(FALSE);
}
}
bool
SetInt(Val, ValStr)
VALUE *Val;
char *ValStr;
{
int I;
if (sscanf(ValStr, "%d", &I) == 1) {
Val->val_type = integer;
Val->val_u.udt_int = I;
return(TRUE);
} else {
return(FALSE);
}
}
bool
SetBool(Val, ValStr)
VALUE *Val;
char *ValStr;
{
register int i, n;
char s[32];
n = min(strlen(ValStr),sizeof(s)-1);
for (i=0; i<n; i++)
s[i] = isupper(ValStr[i])? tolower(ValStr[i]) : ValStr[i];
s[i] = (char)NULL;
n = i - 1;
if (
strncmp(s, "true", n) == 0 ||
strncmp(s, "on", n) == 0 ||
strncmp(s, "yes", n) == 0 ||
strncmp(s, "1", n) == 0)
{
Val->val_type = boolean;
Val->val_u.udt_bool = TRUE;
return(TRUE);
} else if (
strncmp(s, "false", n) == 0 ||
strncmp(s, "off", n) == 0 ||
strncmp(s, "no", n) == 0 ||
strncmp(s, "0", n) == 0)
{
Val->val_type = boolean;
Val->val_u.udt_bool = FALSE;
return(TRUE);
} else {
return(FALSE);
}
}
bool
SetByte(Val, ValStr)
VALUE *Val;
char *ValStr;
{
char C;
Val->val_type = byte;
if (sscanf(ValStr, "%c", &C) == 1) {
Val->val_u.udt_byte = (char)C;
return(TRUE);
} else {
return(FALSE);
}
}
bool
SetInterval(Val, ValStr)
VALUE *Val;
char *ValStr;
{
double lo, hi;
Val->val_type = interval;
if (sscanf(ValStr, "%lf,%lf", &lo,&hi) == 2) {
Val->val_u.udt_interval.int_lo = lo;
Val->val_u.udt_interval.int_hi = hi;
return(TRUE);
} else {
return(FALSE);
}
}
bool
SetSet(Val, ValStr, ValType, WidType)
VALUE *Val;
char *ValStr;
char *ValType;
int WidType;
{
int i;
SET *S;
char *LeftBrace, *RightBrace;
char *Start;
char *sp;
bool Escape;
int WidStr;
char s[128];
char *SkipBlanks(char *);
Val->val_type = set;
S = &Val->val_u.udt_set;
S->list_n = 0;
S->list_head = (LATOM *)NULL;
S->list_tail = (LATOM *)NULL;
if ((LeftBrace = strchr(ValStr, '{')) == (char *)NULL) {
/*error*/
fprintf(stderr,"(SetSet) Invalid set specification: \"%s\" (missing left brace).\n", ValStr);
exit(0);
}
Start = LeftBrace+1;
if ((RightBrace = strchr(ValStr, '}')) == (char *)NULL) {
/*error*/
fprintf(stderr,"(SetSet) Invalid set specification: \"%s\" (missing right brace).\n", ValStr);
exit(0);
}
WidStr = RightBrace - Start;
for (sp=Start; *sp && *sp != '}'; ) {
/* sp = SkipBlanks(sp); */
for ( Escape=FALSE,i=0; *sp && (Escape==TRUE || (Escape==FALSE && *sp != ',' && *sp != '}')); sp++) {
if (Escape == TRUE) {
s[i++] = *sp;
Escape = !Escape;
} else if (*sp == '\\' && Escape == FALSE) {
Escape = !Escape;
} else {
assert(*sp != '\\' && Escape == FALSE);
s[i++] = *sp;
}
}
s[i] = (char)NULL;
Append(S, (generic *)StrDup(s));
if (*sp == ',')
++sp;
}
return(TRUE);
}
bool
SetRect(Val, ValStr)
VALUE *Val;
char *ValStr;
{
register char *sp;
register int i;
FLOAT *R;
char *LeftBrace, *RightBrace;
char *Start;
char s[128];
char *SkipBlanks(char *);
double atof();
Val->val_type = rect;
R = Val->val_u.udt_rect.r_diag;
if ((LeftBrace = strchr(ValStr, '{')) == (char *)NULL) {
/*error*/
fprintf(stderr,"(SetRect) Invalid rect specification: \"%s\" (missing left brace).\n", ValStr);
exit(0);
}
Start = LeftBrace+1;
if ((RightBrace = strchr(ValStr, '}')) == (char *)NULL) {
/*error*/
fprintf(stderr,"(SetRect) Invalid rect specification: \"%s\" (missing right brace).\n", ValStr);
exit(0);
}
for (sp=Start; *sp && *sp != '}'; ) {
sp = SkipBlanks(sp);
for ( i=0; *sp && *sp != ',' && *sp != '}'; sp++) {
s[i++] = *sp;
}
s[i] = (char)NULL;
*R++ = atof(s);
if (*sp == ',')
++sp;
}
return(TRUE);
}
char *
SkipBlanks(s)
register char *s;
{
while(isspace(*s))
++s;
return(s);
}
void
PrintUsage(Fp, Usage, Function, Symbols)
FILE *Fp;
char *Usage[];
char *Function[];
ARGDEF *Symbols[];
{
register int i;
for (i=0; Usage[i]; i++)
fputs(Usage[i], Fp);
for (i=0; Function[i]; i++)
fputs(Function[i], Fp);
fprintf(Fp, "Options:\n");
for (i=0; Symbols[i]; i++) {
fputc('\t', Fp);
PrintArgDef(Fp, Symbols[i]);
}
}
bool
ParseHelp(Usage, Function, Symbols, arg)
char *Usage;
char *Function;
ARGDEF *Symbols[];
char *arg;
{
bool Help();
char *EqualSign;
if (strncmp(arg, "Help", 4)==0 || strncmp(arg, "help", 4)==0) {
if ((EqualSign = strchr(arg,'=')) == (char *)NULL)
return(Help(Usage, Function, Symbols, "All"));
else
return(Help(Usage, Function, Symbols, EqualSign+1));
}
return(FALSE);
}
bool
Help(Usage, Function, Symbols, arg)
char *Usage[];
char *Function[];
ARGDEF *Symbols[];
char *arg;
{
register int i, j;
extern VALUE V_Verbose;
if (strcmp(arg, "All")==0 || strcmp(arg,"all")==0) {
if (VtoBoolean(V_Verbose)) {
for (i=0; Usage[i]; i++)
fputs(Usage[i], stdout);
for (i=0; Function[i]; i++)
fputs(Function[i], stdout);
fprintf(stdout, "Options:\n");
for (i=0; Symbols[i]; i++) {
fputc('\t', stdout);
PrintArgDef(stdout, Symbols[i]);
if ( Symbols[i]->ad_helptext != (char **)NULL) {
for (j=0; Symbols[i]->ad_helptext[j]; j++)
fputs(Symbols[i]->ad_helptext[j], stdout);
}
fputc('\n', stdout);
}
} else {
fputs(Usage[0], stdout);
fputs(Function[0], stdout);
fprintf(stderr, "Options:\n");
for (i=0; Symbols[i]; i++) {
fputc('\t', stdout);
PrintArgDef(stdout, Symbols[i]);
}
}
return(TRUE);
} else {
/* find entry in symbol table */
for (i=0; Symbols[i]; i++) {
if (strcmp(arg,Symbols[i]->ad_id) == 0) {
/* found */
fputc('\t', stdout);
PrintArgDef(stdout, Symbols[i]);
if (VtoBoolean(V_Verbose) && Symbols[i]->ad_helptext != (char **)NULL) {
for (j=0; Symbols[i]->ad_helptext[j]; j++)
fputs(Symbols[i]->ad_helptext[j], stdout);
fputc('\n', stdout);
}
return(TRUE);
}
}
}
return(FALSE);
}
bool
ParseArg(Symbols, arg)
ARGDEF *Symbols[];
char *arg;
{
register int i;
char *EqualSign;
char *ValueStr;
int wid;
if ((EqualSign = strchr(arg,'=')) == (char *)NULL) {
ValueStr = arg;
wid = strlen(ValueStr);
} else {
ValueStr = EqualSign + 1;
wid = EqualSign - arg;
}
/* find entry in symbol table */
for (i=0; Symbols[i]; i++) {
if (strncmp(arg,Symbols[i]->ad_id, wid) == 0) {
/* found */
return(ParseEntry(Symbols[i], ValueStr));
}
}
return(FALSE);
}
bool
ParseEntry(Entry, arg)
ARGDEF *Entry;
char *arg;
{
char *StartOpt, *StartType;
char *BarOpt;
char *BarType;
int WidOpt, WidType;
StartOpt = Entry->ad_options;
StartType = Entry->ad_opttype;
do {
if ((BarOpt = strchr(StartOpt,'|')) == (char *)NULL) {
WidOpt = strlen(StartOpt);
} else {
WidOpt = BarOpt - StartOpt;
}
if ((BarType = strchr(StartType,'|')) == (char *)NULL) {
WidType = strlen(StartType);
} else {
WidType = BarType - StartType;
}
if (strncmp(StartType, "string", WidType) == 0) {
if (ParseString(Entry, StartOpt, WidOpt, arg) == TRUE)
return(TRUE);
else {
StartOpt = ++BarOpt;
StartType = ++BarType;
continue;
}
} else if (strncmp(StartType, "dbl", WidType) == 0) {
if (ParseDbl(Entry, arg) == TRUE)
return(TRUE);
else {
StartOpt = ++BarOpt;
StartType = ++BarType;
continue;
}
} else if (strncmp(StartType, "float", WidType) == 0) {
if (ParseFloat(Entry, arg) == TRUE)
return(TRUE);
else {
StartOpt = ++BarOpt;
StartType = ++BarType;
continue;
}
} else if (strncmp(StartType, "int", WidType) == 0) {
if (ParseInt(Entry, arg) == TRUE)
return(TRUE);
else {
StartOpt = ++BarOpt;
StartType = ++BarType;
continue;
}
} else if (strncmp(StartType, "boolean", WidType) == 0) {
if (ParseBool(Entry, arg) == TRUE)
return(TRUE);
else {
StartOpt = ++BarOpt;
StartType = ++BarType;
continue;
}
} else if (strncmp(StartType, "byte", WidType) == 0) {
if (ParseByte(Entry, arg) == TRUE)
return(TRUE);
else {
StartOpt = ++BarOpt;
StartType = ++BarType;
continue;
}
} else if (strncmp(StartType, "interval", WidType) == 0) {
if (ParseInterval(Entry, arg) == TRUE)
return(TRUE);
else {
StartOpt = ++BarOpt;
StartType = ++BarType;
continue;
}
} else if (strncmp(StartType, "set", min(WidType,3)) == 0) {
if (ParseSet(Entry, arg, StartType,WidType) == TRUE) {
return(TRUE);
} else {
StartOpt = ++BarOpt;
StartType = ++BarType;
continue;
}
} else if (strncmp(StartType, "rect", WidType) == 0) {
if (ParseRect(Entry, arg) == TRUE) {
return(TRUE);
} else {
StartOpt = ++BarOpt;
StartType = ++BarType;
continue;
}
} else {
fprintf(stderr, "Internal Error: invalid option type string: \"%s\"\n", StartType);
PrintArgDef(stderr,Entry);
errno = EINVAL;
exit(errno);
}
} while(StartOpt != (char)NULL && StartType != (char)NULL);
return(TRUE);
}
bool
ParseString(Entry, Option, n, arg)
ARGDEF *Entry;
char *Option;
int n;
char *arg;
{
if (*Option == '*') {
/* Match any string */
Entry->ad_value->val_type = string;
Entry->ad_value->val_u.udt_string = StrDup(arg);
return(TRUE);
} else if (arg!=(char *)NULL && strncmp(arg,Option,strlen(arg)) == 0) {
/* Matches option */
Entry->ad_value->val_type = string;
Entry->ad_value->val_u.udt_string = StrDup(arg);
return(TRUE);
} else {
return(FALSE);
}
}
char *
StrDup(Str)
char *Str;
{
register int n;
register char *Dup;
if (Str == (char *)NULL)
return((char *)NULL);
n = strlen(Str);
if ((Dup = malloc(n+1)) == (char *)NULL) {
perror("(StrDup) ");
assert(Dup != (char *)NULL);
exit(errno);
}
memcpy(Dup, Str, n+1);
return(Dup);
}
bool
ParseDbl(Entry, arg)
ARGDEF *Entry;
char *arg;
{
return(SetDbl(Entry->ad_value, arg));
}
bool
ParseFloat(Entry, arg)
ARGDEF *Entry;
char *arg;
{
return(SetFloat(Entry->ad_value, arg));
}
bool
ParseInt(Entry, arg)
ARGDEF *Entry;
char *arg;
{
return(SetInt(Entry->ad_value, arg));
}
bool
ParseBool(Entry, arg)
ARGDEF *Entry;
char *arg;
{
return(SetBool(Entry->ad_value, arg));
}
bool
ParseByte(Entry, arg)
ARGDEF *Entry;
char *arg;
{
return(SetByte(Entry->ad_value, arg));
}
bool
ParseInterval(Entry, arg)
ARGDEF *Entry;
char *arg;
{
return(SetInterval(Entry->ad_value, arg));
}
bool
ParseSet(Entry, arg, Type, WidType)
ARGDEF *Entry;
char *arg;
char *Type;
int WidType;
{
return(SetSet(Entry->ad_value, arg, Type, WidType));
}
bool
ParseRect(Entry, arg)
ARGDEF *Entry;
char *arg;
{
return(SetRect(Entry->ad_value, arg));
}
void
PrintArgDef(Fp, Def)
FILE *Fp;
ARGDEF *Def;
{
fprintf(Fp, "%s=", Def->ad_id);
fprintf(Fp, "[%s]", Def->ad_options);
fprintf(Fp, " default: %s\n", Def->ad_default);
fflush(Fp);
}
void
PrintArg(Fp, Def)
FILE *Fp;
ARGDEF *Def;
{
LATOM *A;
switch(Def->ad_value->val_type) {
default:
fprintf(Fp,"%s=<Invalid datatype>!\n", Def->ad_id);
break;
case boolean:
fprintf(Fp,"%s=%s\n",
Def->ad_id,
Def->ad_value->val_u.udt_bool? "TRUE":"FALSE");
break;
case integer:
fprintf(Fp,"%s=%d\n",Def->ad_id,Def->ad_value->val_u.udt_int);
break;
case dbl:
fprintf(Fp,"%s=%lg\n",Def->ad_id,Def->ad_value->val_u.udt_dbl);
break;
case flt:
fprintf(Fp,"%s=%g\n",Def->ad_id,Def->ad_value->val_u.udt_flt);
break;
case byte:
fprintf(Fp,"%s=%c\n",Def->ad_id,Def->ad_value->val_u.udt_byte);
break;
case string:
fprintf(Fp,"%s=\"%s\"\n",Def->ad_id,Def->ad_value->val_u.udt_string);
break;
case interval:
fprintf(Fp,"%s=%g,%g\n",Def->ad_id,Def->ad_value->val_u.udt_interval);
break;
case set:
fprintf(Fp,"%s={\n",Def->ad_id);
for (A=Def->ad_value->val_u.udt_set.list_head; A; A=A->la_next)
if (A->la_next)
fprintf(Fp,"\t\t<%s>,\n",(char *)A->la_p);
else
fprintf(Fp,"\t\t<%s>\n",(char *)A->la_p);
fprintf(Fp, "\t}\n");
break;
case rect:
fprintf(
Fp,
"%s={%g,%g, %g,%g}\n",
Def->ad_id,
Def->ad_value->val_u.udt_rect.r_diag[0],
Def->ad_value->val_u.udt_rect.r_diag[1],
Def->ad_value->val_u.udt_rect.r_diag[2],
Def->ad_value->val_u.udt_rect.r_diag[3]
);
break;
}
}