aboutsummaryrefslogtreecommitdiff
path: root/source/config.c
blob: 7fa97d0cdfcb63efc59acee380ded84c5b1b3ed6 (plain)
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;
}