1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#include "kpl.h"
static kpl_config default_config = {
.argc = -1, .main_module_arg_index = -1,
.argv = NULL, .module_extension = ".kpl",
.io = { .queue_pow = 12 },
.thread = { .thread_count = -1 },
.memory = {}
};
void kpl_config_init(kpl_config *config) {
memcpy(config, &default_config, sizeof(kpl_config));
}
typedef int32_t kpl_arg_match_fn(const char *match_str, const int32_t match_str_index, kpl_config *config);
typedef struct {
const char *match_str, *help_message;
kpl_arg_match_fn *arg_match_fn;
} kpl_arg_match;
static int32_t kpl_arg_match_help(const char *match_str, const int32_t match_str_index, kpl_config *config);
static int32_t kpl_arg_match_module_extension(const char *match_str, const int32_t match_str_index, kpl_config *config) {
config->module_extension = match_str + match_str_index;
return KPL_EXIT_CODE_SUCCESS;
}
static kpl_arg_match arg_match_array[] = {
{
.match_str = "--module-extension=",
.help_message="[WORD], Change the module extension for imported files (default .kpl)",
.arg_match_fn = kpl_arg_match_module_extension
},
{ .match_str = "--help", .help_message = ", Show help", .arg_match_fn = kpl_arg_match_help },
{ .match_str = NULL, .help_message = NULL, .arg_match_fn = NULL }
};
static int32_t kpl_arg_match_help(const char *match_str, const int32_t match_str_index, kpl_config *config) {
(void) match_str;
(void) match_str_index;
(void) config;
printf("\nUsage " KPL_COLOR(BOLD) "%s" KPL_COLOR(RESET) KPL_COLOR(WHITE) " [OPTIONS] [FILE]" KPL_COLOR(RESET)
KPL_COLOR(BOLD) "%s\n\n" KPL_COLOR(RESET), config->argv[0], config->module_extension);
printf("Where " KPL_COLOR(WHITE) "[OPTIONS]" KPL_COLOR(RESET) " are:\n");
const kpl_arg_match *match_array = arg_match_array;
while (match_array->match_str) {
printf(KPL_COLOR(LIGHT_YELLOW) "\t%s" KPL_COLOR(RESET) "%s\n",
match_array->match_str, match_array->help_message);
match_array++;
}
putchar('\n');
return KPL_EXIT_CODE_HELP;
}
static bool kpl_valid_match_str_index(const char *match_str_array, const char *match_str_arg, int32_t match_str_index) {
return match_str_array[match_str_index] &&
match_str_array[match_str_index] == match_str_arg[match_str_index];
}
static bool kpl_valid_match_str(const char *match_str_array, const char *match_str_arg, int32_t match_str_index) {
return !match_str_array[match_str_index] && (!match_str_arg[match_str_index] ||
(match_str_arg[match_str_index] && match_str_array[match_str_index - 1] == '='));
}
bool kpl_config_valid_module_exension(kpl_config *config, const char *module_name) {
size_t name_length = strlen(module_name), module_extension_length = strlen(config->module_extension);
return name_length > module_extension_length &&
strcmp(module_name + name_length - module_extension_length, config->module_extension) == 0;
}
int32_t kpl_config_parse_args(kpl_config *config, const int32_t argc, const char *argv[]) {
config->argc = argc;
config->argv = argv;
int32_t arg_index = 1;
while (arg_index < argc) {
int32_t match_str_index = 0;
const char *match_str_arg = argv[arg_index];
const kpl_arg_match *match_array = arg_match_array;
while (match_array->match_str) {
while (kpl_valid_match_str_index(match_array->match_str, match_str_arg, match_str_index))
match_str_index++;
if (kpl_valid_match_str(match_array->match_str, match_str_arg, match_str_index)) {
int32_t exit_status = match_array->arg_match_fn(match_str_arg, match_str_index, config);
if (exit_status != KPL_EXIT_CODE_SUCCESS)
return exit_status;
break;
}
match_str_index = 0;
match_array++;
}
if (!match_array->match_str)
break;
arg_index++;
}
if (arg_index == argc)
return KPL_EXIT_CODE_SUCCESS;
if (!kpl_config_valid_module_exension(config, argv[arg_index])) {
printf(KPL_COLOR(LIGHT_RED) "\nInvalid " KPL_COLOR(RESET)
KPL_COLOR(WHITE) "[OPTION]/[FILE]: " KPL_COLOR(RESET)
KPL_COLOR2(BOLD, LIGHT_RED) "%s\n" KPL_COLOR(RESET), argv[arg_index]);
return kpl_arg_match_help(NULL, 0, config);
}
config->main_module_arg_index = arg_index;
return KPL_EXIT_CODE_SUCCESS;
}
|