home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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;
- }
- }
-