#include <ctype.h>
#include <nidl.h>
#include <getflags.h>
#include <command.h>
#include <driver.h>
#include <message.h>
#define NFLAGS 128
static unsigned char option_count[NFLAGS] = {0};
static int other_count = 0;
static char *(other_flags[NFLAGS]) = {0};
char *last_string;
int flags_option_count
(
OPTIONS table[],
char *option
)
{
int o;
if (*option == '-')
option++;
for (o = 0; table[o].option && o < NFLAGS; o++)
{
if (strcmp(option, table[o].option) == 0)
return((int)option_count[o]);
}
return(-1);
}
void flags_incr_count
(
OPTIONS table[],
char *option,
int delta
)
{
int o;
if (*option == '-')
option++;
for (o = 0; table[o].option && o < NFLAGS; o++)
{
if (strlen(option) != strlen(table[o].option))
continue;
if (strcmp(option, table[o].option) == 0)
{
option_count[o] += delta;
return;
}
}
}
int flags_other_count
(
void
)
{
return(other_count);
}
char *flags_other
(
int index
)
{
if (0 <= index && index < other_count)
return(other_flags[index]);
else
return(NULL);
}
boolean is_number
(
char *str
)
{
if (*str == '+' || *str == '-')
str++;
for ( ; *str != '\0' ; str++)
if (!isdigit(*str))
return false;
return true;
}
void getflags
(
int ac,
char **av,
OPTIONS table[]
)
{
int o;
int optlen;
int nflags, type;
int vflag;
boolean optval;
register char **pstring;
register char *pchar;
register int *pint;
register char *flag = NULL;
register long *plong;
register double *pfloat;
last_string = NULL;
while (ac > 0)
{
thisf:
for (o = 0; table[o].option; o++)
{
flag = *av;
if (flag[0] == '-')
flag++;
if (strlen(flag) != strlen(table[o].option))
continue;
if (strcmp(flag, table[o].option) == 0)
{
optval = false;
matchf:
nflags = (table[o].ftype >> 8) & 0xFF;
vflag = nflags & VARARGFLAG;
nflags &= MULTARGMASK;
if (nflags <= 0)
nflags = 1;
type = table[o].ftype & 0xFF;
switch (type)
{
default:
INTERNAL_ERROR("Illegal option type");
case INTARG:
pint = (int *)table[o].dest;
if (vflag)
pint += option_count[o];
if (nflags && (ac > 1))
{
if (is_number(av[1]))
{
GETINT(*pint++);
}
else
goto nextf;
if (ac > 0 && vflag && **av == '-') goto thisf;
option_count[o]++;
}
goto nextf;
case STRARG:
pstring = (char **)table[o].dest;
if (vflag)
pstring += option_count[o];
option_count[o]++;
if (nflags && (ac > 1))
{
GETSTR(*pstring);
if (ac > 0 && vflag && **av == '-')
{
*pstring = NULL;
goto thisf;
}
}
goto nextf;
case OSTRARG:
pstring = (char **)table[o].dest;
if (!optval)
{
if (ac == 1 || (ac > 1 && *av[1] == '-'))
{
*pstring = "";
goto nextf;
}
}
if (vflag)
pstring += option_count[o];
if (nflags && (ac > 1))
{
GETSTR(*pstring);
if (ac > 0 && vflag && **av == '-')
{
*pstring = NULL;
goto thisf;
}
last_string = *pstring;
option_count[o]++;
}
goto nextf;
case TOGGLEARG:
pchar = (char *)table[o].dest;
*pchar = ~*pchar;
goto nextf;
case ASSERTARG:
pchar = (char *)table[o].dest;
*pchar = true;
goto nextf;
case DENYARG:
pchar = (char *)table[o].dest;
*pchar = false;
goto nextf;
case CHRARG:
pchar = (char *)table[o].dest;
if (vflag)
pchar += option_count[o];
if (nflags && (ac > 1))
{
GETCH(*pchar++);
if (ac > 0 && vflag && **av == '-') goto thisf;
option_count[o]++;
}
goto nextf;
case FLTARG:
pfloat = (double *)table[o].dest;
if (vflag)
pfloat += option_count[o];
if (nflags && (ac > 1))
{
GETFLT(*pfloat++);
if (ac > 0 && vflag && **av == '-') goto thisf;
option_count[o]++;
}
goto nextf;
case LONGARG:
plong = (long *)table[o].dest;
if (vflag)
plong += option_count[o];
if (nflags && (ac > 1))
{
if (is_number(av[1]))
{
GETLONG(*plong++);
}
else
goto nextf;
if (ac > 0 && vflag && **av == '-') goto thisf;
option_count[o]++;
}
goto nextf;
}
}
}
if (**av == '-')
{
for (o = 0; table[o].option; o++)
{
optlen = strlen(table[o].option);
if (strncmp(flag, table[o].option, optlen) == 0)
{
type = table[o].ftype & 0xFF;
if (type==TOGGLEARG || type==ASSERTARG || type==DENYARG)
{
message_print(NIDL_OPTNOVAL, table[o].option);
CMD_explain_args();
exit(pgm_error);
}
optval = true;
*av += optlen+1;
ac++;
av--;
goto matchf;
}
}
message_print(NIDL_UNKFLAG, *av);
CMD_explain_args();
exit(pgm_error);
}
else
{
other_flags[other_count++] = *av;
}
nextf:
ac--;
av++;
}
}
#define yes_no(x) (x? "Yes" : "No")
#define no_yes(x) (x? "No" : "Yes")
void printflags
(
OPTIONS table[]
)
{
register int o;
register int nflags;
register int type;
int vflag;
int *pint;
char *pchar;
char **pstring;
long *plong;
double *pdouble;
int option_len;
option_len = 0;
for (o = 0; table[o].option; o++)
if (strlen(table[o].option) > option_len)
option_len = strlen(table[o].option);
option_len += 3;
message_print(NIDL_OPTIONSTABLE);
for (o = 0; table[o].option; o++)
{
type = table[o].ftype;
if (type & HIDARG) continue;
nflags = (type >> 8) & 0xFF;
vflag = nflags & VARARGFLAG;
if (vflag)
nflags = option_count[o];
type &= 255;
fprintf(stderr, " %-*s", option_len, table[o].option);
if (!vflag && nflags <= 0)
nflags = 1;
switch (type)
{
default:
fprintf(stderr, "\tillegal option in printflags: %d\n",
table[o].ftype);
exit(pgm_error);
case INTARG:
pint = (int *)table[o].dest;
while (nflags-- > 0)
fprintf(stderr, "\t%d", *pint++);
fprintf(stderr, "\n");
break;
case STRARG:
case OSTRARG:
pstring = (char **)table[o].dest;
while (nflags-- > -0)
fprintf(stderr, "\t%s", *pstring++);
fprintf(stderr, "\n");
break;
case TOGGLEARG:
case ASSERTARG:
pchar = (char *)table[o].dest;
while (nflags-- > 0)
fprintf(stderr, "\t%s", yes_no(*pchar++));
fprintf(stderr, "\n");
break;
case DENYARG:
pchar = (char *)table[o].dest;
while (nflags-- > 0)
fprintf(stderr, "\t%s", no_yes(*pchar++));
fprintf(stderr, "\n");
break;
case CHRARG:
pchar = (char *)table[o].dest;
while (nflags-- > 0)
fprintf(stderr, "\t%c", *pchar++);
fprintf(stderr, "\n");
break;
case FLTARG:
pdouble = (double *)table[o].dest;
while (nflags-- > 0)
fprintf(stderr, "\t%.3f", *pdouble++);
fprintf(stderr, "\n");
break;
case LONGARG:
plong = (long *)table[o].dest;
while (nflags-- > 0)
fprintf(stderr, "\t%ld", *plong++);
fprintf(stderr, "\n");
break;
}
}
fprintf(stderr, "\n");
}