Files
CgeArgs/Args.c

135 lines
3.2 KiB
C
Raw Normal View History

2026-08-17 15:06:08 +03:00
#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;
}