fixed segfaults

This commit is contained in:
Sven Vogel 2024-06-01 01:00:22 +02:00
parent 8f24596779
commit 3a8796a462
4 changed files with 94 additions and 58 deletions

View File

@ -44,7 +44,7 @@ TargetConfig* default_target_config_from_args(int argc, char *argv[]) {
} else if (strcmp(option, "--mode=lib") == 0) { } else if (strcmp(option, "--mode=lib") == 0) {
config->mode = Library; config->mode = Library;
} else { } else {
config->root_module = option; config->root_module = strdup(option);
} }
} }

View File

@ -217,7 +217,11 @@ void print_unit_statistics(ModuleFileStack *file_stack) {
stats.error_count += file->statistics.error_count; stats.error_count += file->statistics.error_count;
} }
printf("%d files generated ", file_stack->files->len); if (stats.info_count + stats.warning_count + stats.error_count < 1) {
return;
}
printf("%d file(s) generated ", file_stack->files->len);
if (stats.info_count > 0) { if (stats.info_count > 0) {
printf("%ld notice(s) ", stats.info_count); printf("%ld notice(s) ", stats.info_count);
@ -233,3 +237,31 @@ void print_unit_statistics(ModuleFileStack *file_stack) {
printf("\n\n"); printf("\n\n");
} }
void print_message(Message kind, const char *fmt, ...) {
const char *accent_color = RESET;
const char *kind_text = "unknown";
switch (kind) {
case Info:
kind_text = "info";
accent_color = CYAN;
break;
case Warning:
kind_text = "warning";
accent_color = YELLOW;
break;
case Error:
kind_text = "error";
accent_color = RED;
break;
}
va_list args;
va_start(args, fmt);
printf("%s%s:%s ", accent_color, kind_text, RESET);
vprintf(fmt, args);
printf("\n\n");
va_end(args);
}

View File

@ -70,6 +70,9 @@ TokenLocation empty_location(void);
[[gnu::nonnull(1), gnu::nonnull(2)]] [[gnu::nonnull(1), gnu::nonnull(2)]]
void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message); void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, const char *message);
[[gnu::nonnull(2)]]
void print_message(Message kind, const char *fmt, ...);
[[gnu::nonnull(1)]] [[gnu::nonnull(1)]]
void print_file_statistics(ModuleFile *file); void print_file_statistics(ModuleFile *file);

View File

@ -32,7 +32,7 @@ static size_t compile_file_to_ast(AST_NODE_PTR ast, ModuleFile *file) {
if (file->handle == NULL) { if (file->handle == NULL) {
INFO("unable to open file: %s", file->path); INFO("unable to open file: %s", file->path);
printf("Cannot open file %s: %s\n", file->path, strerror(errno)); print_message(Error, "Cannot open file %s: %s", file->path, strerror(errno));
return 1; return 1;
} }
@ -96,18 +96,20 @@ void setup(void) {
} }
void build_target(ModuleFileStack *unit, TargetConfig *target) { void build_target(ModuleFileStack *unit, TargetConfig *target) {
printf("Compiling file: %s\n\n", target->root_module); print_message(Info, "Compiling file: %s", target->root_module);
TokenLocation location = { TokenLocation location = new_location(0,0,0,0);
.line_start = 0,
.line_end = 0,
.col_start = 0,
.col_end = 0
};
AST_NODE_PTR ast = AST_new_node(location, AST_Module, NULL); AST_NODE_PTR ast = AST_new_node(location, AST_Module, NULL);
ModuleFile *file = push_file(unit, target->root_module); ModuleFile *file = push_file(unit, target->root_module);
if (compile_file_to_ast(ast, file) == EXIT_SUCCESS) { if (compile_file_to_ast(ast, file) == EXIT_SUCCESS) {
if (target->print_ast) {
}
// TODO: parse AST to semantic values // TODO: parse AST to semantic values
// TODO: backend codegen // TODO: backend codegen
} }
@ -123,7 +125,7 @@ void compile_file(ModuleFileStack *unit, int argc, char *argv[]) {
TargetConfig *target = default_target_config_from_args(argc, argv); TargetConfig *target = default_target_config_from_args(argc, argv);
if (target->root_module == NULL) { if (target->root_module == NULL) {
printf("No input file specified\n"); print_message(Error, "No input file specified.");
delete_target_config(target); delete_target_config(target);
return; return;
} }
@ -133,8 +135,8 @@ void compile_file(ModuleFileStack *unit, int argc, char *argv[]) {
delete_target_config(target); delete_target_config(target);
} }
void build_project_targets(ModuleFileStack *unit, ProjectConfig *config, const char *filter) { void build_project_targets(ModuleFileStack *unit, ProjectConfig *config, int argc, char *argv[]) {
if (strcmp(filter, "all") == 0) { if (argc == 1 && strcmp(argv[0], "all") == 0) {
GHashTableIter iter; GHashTableIter iter;
g_hash_table_iter_init(&iter, config->targets); g_hash_table_iter_init(&iter, config->targets);
@ -144,58 +146,57 @@ void build_project_targets(ModuleFileStack *unit, ProjectConfig *config, const c
while (g_hash_table_iter_next(&iter, (gpointer) &key, (gpointer) &val)) { while (g_hash_table_iter_next(&iter, (gpointer) &key, (gpointer) &val)) {
build_target(unit, val); build_target(unit, val);
} }
} else if (g_hash_table_contains(config->targets, filter)) { } else {
build_target(unit, g_hash_table_lookup(config->targets, filter)); for (int i = 0; i < argc; i++) {
char *target_name = argv[i];
if (g_hash_table_contains(config->targets, target_name)) {
build_target(unit, g_hash_table_lookup(config->targets, target_name));
}
}
} }
} }
void build_project(ModuleFileStack *unit, int argc, char *argv[]) { void build_project(ModuleFileStack *unit, int argc, char *argv[]) {
if (argc >= 1) { if (argc <= 0) {
print_message(Error, "No targets specified.");
return;
}
ProjectConfig *config = default_project_config(); ProjectConfig *config = default_project_config();
int err = load_project_config(config); int err = load_project_config(config);
if (err == PROJECT_OK) { if (err == PROJECT_OK) {
if (argc == 1) { build_project_targets(unit, config, argc, argv);
build_project_targets(unit, config, "all");
} else {
build_project_targets(unit, config, argv[0]);
}
} }
delete_project_config(config); delete_project_config(config);
} else {
printf("Expected 1 target to run\n");
}
} }
void configure_run_mode(int argc, char *argv[]) { void configure_run_mode(int argc, char *argv[]) {
if (argc > 1) { if (argc <= 0) {
INFO("no arguments provided");
print_help();
return;
}
ModuleFileStack files; ModuleFileStack files;
files.files = NULL; files.files = NULL;
if (strcmp(argv[1], "build") == 0) { if (strcmp(argv[0], "build") == 0) {
build_project(&files, argc - 2, &argv[2]); build_project(&files, argc - 1, &argv[1]);
} else if (strcmp(argv[1], "compile") == 0) { } else if (strcmp(argv[0], "compile") == 0) {
compile_file(&files, argc - 2, &argv[2]); compile_file(&files, argc - 1, &argv[1]);
} else { } else {
printf("invalid mode of operation\n"); print_message(Error, "Invalid mode of operation. Rerun with --help.");
} }
if (files.files == NULL) { if (files.files == NULL) {
printf("No input files, nothing to do.\n\n"); print_message(Error, "No input files, nothing to do.");
exit(1); exit(1);
} }
print_unit_statistics(&files); print_unit_statistics(&files);
delete_files(&files); delete_files(&files);
return;
}
INFO("no arguments provided");
print_help();
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -203,9 +204,9 @@ int main(int argc, char *argv[]) {
setup(); setup();
atexit(close_file); atexit(close_file);
printf("running GSC version %s\n", GSC_VERSION); print_message(Info, "running GSC version %s", GSC_VERSION);
configure_run_mode(argc, argv); configure_run_mode(argc - 1, &argv[1]);
return 0; return 0;
} }