#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "control.h"
#include "error.h"
#include "trace.h"
static void printAll ();
enum actionType {NO_ARG, STRING_ARG};
enum errorNum {NORMAL, WANT_ARG, WRONG_ARG};
typedef struct
{
char *name;
char *arg;
int size;
char *desc;
enum actionType argType;
enum errorNum (*action)();
} chunk;
static int maxSize = 0;
static char **allStrs;
static int current = 0;
static int tail = 0;
int f ()
{
return 1;
}
static enum errorNum dash_debug ()
{
current++;
if (current>=tail) {
return WANT_ARG;
}
if (strcmp(allStrs[current], "0")==0) {
Control_debugLevel = 0;
return NORMAL;
}
else if (strcmp(allStrs[current], "1")==0) {
Control_debugLevel = 1;
return NORMAL;
}
else if (strcmp(allStrs[current], "2")==0) {
Control_debugLevel = 2;
return NORMAL;
}
else if (strcmp(allStrs[current], "3")==0) {
Control_debugLevel = 3;
return NORMAL;
}
else {
return WRONG_ARG;
}
}
static enum errorNum dash_h ()
{
printAll ();
exit (1);
}
// "Trace"
static enum errorNum dash_trace ()
{
current++;
if (current>=tail) {
return WANT_ARG;
}
if (strcmp(allStrs[current], "@")==0) {
Control_tracedAll = 1;
return NORMAL;
}
else {
Control_tracedFuncs[Control_tracedLast++]
= allStrs[current];
return NORMAL;
}
}
// assert
static enum errorNum dash_assert ()
{
Control_assert = 1;
return NORMAL;
}
chunk allOptions[] =
{
{
.name = "-assert",
.arg = "",
.size = 0,
.desc = "enable assertions",
.argType = NO_ARG,
.action = dash_assert
},
{
.name = "-debug",
.arg = "{0|1|2|3}",
.size = 0,
.desc = "what debug level to be",
.argType = STRING_ARG,
.action = dash_debug
},
{
.name = "-h",
.arg = "",
.size = 0,
.desc = "show this message",
.argType = NO_ARG,
.action = dash_h
},
{
.name = "-trace",
.arg = "<name>",
.size = 0,
.desc = "which function to trace, use @ to trace all function",
.argType = STRING_ARG,
.action = dash_trace
},
{
.name = 0
}
};
static void printSpaces (int n)
{
while (n--)
printf (" ");
}
static void printAll ()
{
int i;
for (i=0; allOptions[i].name; i++)
{
printf(" %s %s ", allOptions[i].name, allOptions[i].arg);
printSpaces(maxSize-allOptions[i].size);
printf ("%s\n", allOptions[i].desc);
}
}
void prepass (int argc, char *argv[])
{
int j;
for (j=0; allOptions[j].name; j++)
{
if (allOptions[j].size==0)
allOptions[j].size = strlen(allOptions[j].name)+
strlen(allOptions[j].arg);
if (allOptions[j].size > maxSize)
maxSize =allOptions[j].size;
}
}
static void printAllOptions ();
void handleArgs (int argc, char *argv[])
{
allStrs = argv;
tail = argc;
if (maxSize ==0)
prepass (argc, argv);
int j;
for (; current<argc; current++) {
if (argv[current][0]!='-')
continue;
for (j=0; allOptions[j].name; j++) {
if (strcmp(argv[current], allOptions[j].name)==0) {
switch (allOptions[j].action (allOptions[j].name)) {
case NORMAL:
break;
case WANT_ARG:
printf ("\"%s\" wants an argument: \"%s\"\n",
allOptions[j].name, allOptions[j].arg);
printAll ();
exit (1);
break;
case WRONG_ARG:
printf ("\"%s\" given wrong argument, wants: \"%s\"\n",
allOptions[j].name, allOptions[j].arg);
printAll ();
exit (1);
break;
default:
Error_error ("no this case!");
break;
}
break;
}
}
if (allOptions[j].name==0) {
printf ("unknown options: %s\n", argv[current]);
printAll ();
exit (1);
}
}
if (Control_debugLevel>=3)
printAllFlags ();
}