135 lines
3.2 KiB
C
135 lines
3.2 KiB
C
|
|
#include "CgeArgs.h"
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
|
||
|
|
static void parseArg(CgeArgs *arg, const char *value) {
|
||
|
|
if (value == NULL && arg->type != CGE_ARGS_BOOL)
|
||
|
|
return;
|
||
|
|
|
||
|
|
switch (arg->type) {
|
||
|
|
case CGE_ARGS_STRING:
|
||
|
|
*(const char**)arg->data = value;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case CGE_ARGS_FLOAT:
|
||
|
|
*(float*)arg->data = strtod(value, NULL);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case CGE_ARGS_DOUBLE:
|
||
|
|
*(double*)arg->data = strtod(value, NULL);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case CGE_ARGS_INT:
|
||
|
|
*(int*)arg->data = atoi(value);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case CGE_ARGS_BOOL:
|
||
|
|
*(int*)arg->data = 1;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static CgeArgs *findShort(CgeArgs *args, size_t size, char symbol) {
|
||
|
|
size_t i;
|
||
|
|
|
||
|
|
for (i = 0; i < size; i++) {
|
||
|
|
if (args[i].shortName == symbol)
|
||
|
|
return args + i;
|
||
|
|
}
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
static CgeArgs *findLong(CgeArgs *args, size_t size, char *value) {
|
||
|
|
char *equalSign;
|
||
|
|
size_t i;
|
||
|
|
|
||
|
|
equalSign = strchr(value, '=');
|
||
|
|
for (i = 0; i < size; i++) {
|
||
|
|
if (!args[i].longName)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
if (equalSign) {
|
||
|
|
if (!strncmp(args[i].longName, value, strlen(args[i].longName)))
|
||
|
|
return args + i;
|
||
|
|
} else {
|
||
|
|
if (!strcmp(args[i].longName, value))
|
||
|
|
return args + i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
int CgeArgsParse(CgeArgs *args, size_t size, int argc, char **argv) {
|
||
|
|
int i, ogArgc = argc;
|
||
|
|
|
||
|
|
for (i = 1; i < argc;) {
|
||
|
|
int isFlag = 0;
|
||
|
|
|
||
|
|
if (!strcmp(argv[i], "--"))
|
||
|
|
return i + 1;
|
||
|
|
|
||
|
|
if (argv[i][0] == '-' && argv[i][1] != '-') {
|
||
|
|
int j;
|
||
|
|
|
||
|
|
for (j = 1; argv[i][j]; j++) {
|
||
|
|
CgeArgs *arg;
|
||
|
|
|
||
|
|
arg = findShort(args, size, argv[i][j]);
|
||
|
|
if (!arg) {
|
||
|
|
fprintf(stderr, "Unknown argument: %c\n", argv[i][j]);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
isFlag = 1;
|
||
|
|
|
||
|
|
if (arg->type != CGE_ARGS_BOOL) {
|
||
|
|
if (argv[i][j + 1])
|
||
|
|
parseArg(arg, argv[i] + j + 1);
|
||
|
|
else
|
||
|
|
parseArg(arg, (i + 1 < argc) ? argv[++i] : NULL);
|
||
|
|
break;
|
||
|
|
} else {
|
||
|
|
parseArg(arg, NULL);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else if (argv[i][0] == '-' && argv[i][1] == '-') {
|
||
|
|
CgeArgs *arg;
|
||
|
|
|
||
|
|
arg = findLong(args, size, argv[i] + 2);
|
||
|
|
if (!arg) {
|
||
|
|
fprintf(stderr, "Unknown argument: %s\n", argv[i] + 2);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
isFlag = 1;
|
||
|
|
|
||
|
|
if (arg->type != CGE_ARGS_BOOL) {
|
||
|
|
char *equalSign;
|
||
|
|
|
||
|
|
equalSign = strchr(argv[i] + 2, '=');
|
||
|
|
if (equalSign)
|
||
|
|
parseArg(arg, equalSign + 1);
|
||
|
|
else
|
||
|
|
parseArg(arg, (i + 1 < argc) ? argv[++i] : NULL);
|
||
|
|
} else {
|
||
|
|
parseArg(arg, NULL);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!isFlag) {
|
||
|
|
char *arg = argv[i];
|
||
|
|
int j;
|
||
|
|
|
||
|
|
for (j = i; j < ogArgc - 1; j++)
|
||
|
|
argv[j] = argv[j + 1];
|
||
|
|
argv[ogArgc - 1] = arg;
|
||
|
|
argc--;
|
||
|
|
} else {
|
||
|
|
i++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return argc;
|
||
|
|
}
|