diff --git a/src/cfg/opt.c b/src/cfg/opt.c index 95ec3a1..feeafcb 100644 --- a/src/cfg/opt.c +++ b/src/cfg/opt.c @@ -5,6 +5,8 @@ #include #include +#define MAX_TARGETS_PER_PROJECT 100 + TargetConfig default_target_config() { TargetConfig config; @@ -64,26 +66,45 @@ void print_help(void) { #define PROJECT_TOML_ERR 1 #define PROJECT_SEMANTIC_ERR 2 +static void get_bool(bool* boolean, toml_table_t *table, const char* name) { + toml_datum_t datum = toml_bool_in(table, name); + + if (datum.ok) { + *boolean = datum.u.b; + } +} + +static void get_str(char** string, toml_table_t *table, const char* name) { + toml_datum_t datum = toml_string_in(table, name); + + if (datum.ok) { + *string = datum.u.s; + } +} + +static void get_int(int* integer, toml_table_t *table, const char* name) { + toml_datum_t datum = toml_int_in(table, name); + + if (datum.ok) { + *integer = (int) datum.u.i; + } +} + static int parse_project_table(ProjectConfig *config, toml_table_t *project_table) { // project name - toml_datum_t name = toml_string_in(project_table, "name"); - if (!name.ok) { + get_str(&config->name, project_table, "version"); + if (config->name == NULL) { printf("Invalid project configuration: project must have a name\n\n"); return PROJECT_SEMANTIC_ERR; } - config->name = name.u.s; - // project version - toml_datum_t version = toml_string_in(project_table, "version"); - if (version.ok) { - config->name = version.u.s; - } + get_str(&config->name, project_table, "version"); // author names toml_array_t *authors = toml_array_in(project_table, "authors"); if (authors) { - config->authors = g_array_new(FALSE, FALSE, sizeof(char*)); + config->authors = g_array_new(FALSE, FALSE, sizeof(char *)); for (int i = 0;; i++) { toml_datum_t author = toml_string_at(authors, i); @@ -95,15 +116,63 @@ static int parse_project_table(ProjectConfig *config, toml_table_t *project_tabl } // project description - toml_datum_t description = toml_string_in(project_table, "description"); - if (description.ok) { - config->desc = description.u.s; + get_str(&config->desc, project_table, "description"); + // project license + get_str(&config->license, project_table, "license"); + + return PROJECT_OK; +} + +static int get_mode_from_str(TargetCompilationMode* mode, const char* name) { + if (strcmp(name, "application") == 0) { + *mode = Application; + return PROJECT_OK; + } else if (strcmp(name, "library") == 0) { + *mode = Library; + return PROJECT_OK; + } + printf("Invalid project configuration, mode is invalid: %s\n\n", name); + return PROJECT_SEMANTIC_ERR; +} + +static int parse_target(ProjectConfig *config, toml_table_t *target_table, const char* name) { + TargetConfig target_config = default_target_config(); + + target_config.name = (char*) name; + + get_bool(&target_config.print_ast, target_table, "print_ast"); + get_bool(&target_config.print_asm, target_table, "print_asm"); + get_bool(&target_config.print_ir, target_table, "print_ir"); + + get_str(&target_config.root_module, target_table, "root"); + get_str(&target_config.output_directory, target_table, "output"); + get_str(&target_config.archive_directory, target_table, "archive"); + + get_int(&target_config.optimization_level, target_table, "opt"); + + char* mode = NULL; + get_str(&mode, target_table, "mode"); + int err = get_mode_from_str(&target_config.mode, mode); + if (err != PROJECT_OK) { + return err; } - // project license - toml_datum_t license = toml_string_in(project_table, "license"); - if (license.ok) { - config->license = license.u.s; + g_array_append_val(config->targets, target_config); + + return PROJECT_OK; +} + +static int parse_targets(ProjectConfig *config, toml_table_t *root) { + toml_table_t *targets = toml_table_in(root, "target"); + + for (int i = 0; i < MAX_TARGETS_PER_PROJECT; i++) { + const char *key = toml_key_in(targets, i); + + if (!key) + break; + + toml_table_t *target = toml_table_in(targets, key); + parse_target(config, target, key); } return PROJECT_OK; @@ -127,11 +196,12 @@ int load_project_config(ProjectConfig *config) { toml_table_t *project = toml_table_in(conf, "project"); if (project) { - parse_project_table(config, project); - - return PROJECT_OK; + if (parse_project_table(config, project) == PROJECT_OK) { + return parse_targets(config, project); + } + } else { + printf("Invalid project configuration: missing project table\n\n"); } - printf("Invalid project configuration: missing project table\n\n"); toml_free(conf); return PROJECT_SEMANTIC_ERR; diff --git a/src/cfg/opt.h b/src/cfg/opt.h index c407523..ec259e9 100644 --- a/src/cfg/opt.h +++ b/src/cfg/opt.h @@ -42,6 +42,7 @@ typedef struct ProjectConfig_t { char* license; // list of authors GArray* authors; + GArray* targets; } ProjectConfig; TargetConfig default_target_config();