mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-24 22:54:59 -07:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
@@ -392,6 +392,7 @@ struct BuildContext {
|
||||
bool warnings_as_errors;
|
||||
bool hide_error_line;
|
||||
bool terse_errors;
|
||||
bool json_errors;
|
||||
bool has_ansi_terminal_colours;
|
||||
|
||||
bool ignore_lazy;
|
||||
@@ -1270,14 +1271,17 @@ gb_internal String get_fullpath_core_collection(gbAllocator a, String path, bool
|
||||
}
|
||||
|
||||
gb_internal bool show_error_line(void) {
|
||||
return !build_context.hide_error_line;
|
||||
return !build_context.hide_error_line && !build_context.json_errors;
|
||||
}
|
||||
|
||||
gb_internal bool terse_errors(void) {
|
||||
return build_context.terse_errors;
|
||||
}
|
||||
gb_internal bool json_errors(void) {
|
||||
return build_context.json_errors;
|
||||
}
|
||||
gb_internal bool has_ansi_terminal_colours(void) {
|
||||
return build_context.has_ansi_terminal_colours;
|
||||
return build_context.has_ansi_terminal_colours && !json_errors();
|
||||
}
|
||||
|
||||
gb_internal bool has_asm_extension(String const &path) {
|
||||
|
||||
+2
-2
@@ -1204,7 +1204,7 @@ gb_internal void init_universal(void) {
|
||||
}
|
||||
|
||||
if (defined_values_double_declaration) {
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
}
|
||||
|
||||
|
||||
@@ -4504,7 +4504,7 @@ gb_internal void add_import_dependency_node(Checker *c, Ast *decl, PtrMap<AstPac
|
||||
if (found == nullptr) {
|
||||
Token token = ast_token(decl);
|
||||
error(token, "Unable to find package: %.*s", LIT(path));
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
}
|
||||
AstPackage *pkg = *found;
|
||||
GB_ASSERT(pkg->scope != nullptr);
|
||||
|
||||
+1
-1
@@ -1170,7 +1170,7 @@ gb_internal void odin_doc_write_to_file(OdinDocWriter *w, char const *filename)
|
||||
gbFileError err = gb_file_open_mode(&f, gbFileMode_Write, filename);
|
||||
if (err != gbFileError_None) {
|
||||
gb_printf_err("Failed to write .odin-doc to: %s\n", filename);
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
return;
|
||||
}
|
||||
defer (gb_file_close(&f));
|
||||
|
||||
+98
-13
@@ -6,6 +6,7 @@ enum ErrorValueKind : u32 {
|
||||
struct ErrorValue {
|
||||
ErrorValueKind kind;
|
||||
TokenPos pos;
|
||||
TokenPos end;
|
||||
Array<String> msgs;
|
||||
};
|
||||
|
||||
@@ -146,6 +147,7 @@ gb_internal bool global_warnings_as_errors(void);
|
||||
gb_internal bool global_ignore_warnings(void);
|
||||
gb_internal bool show_error_line(void);
|
||||
gb_internal bool terse_errors(void);
|
||||
gb_internal bool json_errors(void);
|
||||
gb_internal bool has_ansi_terminal_colours(void);
|
||||
gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset);
|
||||
|
||||
@@ -168,13 +170,11 @@ gb_internal ERROR_OUT_PROC(default_error_out_va) {
|
||||
isize len = gb_snprintf_va(buf, gb_size_of(buf), fmt, va);
|
||||
isize n = len-1;
|
||||
|
||||
String msg = {};
|
||||
if (n) {
|
||||
msg = copy_string(permanent_allocator(), {(u8 *)buf, n});
|
||||
if (n > 0) {
|
||||
String msg = copy_string(permanent_allocator(), {(u8 *)buf, n});
|
||||
ErrorValue *ev = get_error_value();
|
||||
array_add(&ev->msgs, msg);
|
||||
}
|
||||
|
||||
ErrorValue *ev = get_error_value();
|
||||
array_add(&ev->msgs, msg);
|
||||
}
|
||||
|
||||
gb_global ErrorOutProc *error_out_va = default_error_out_va;
|
||||
@@ -246,6 +246,7 @@ gb_internal void terminal_reset_colours(void) {
|
||||
|
||||
|
||||
gb_internal bool show_error_on_line(TokenPos const &pos, TokenPos end) {
|
||||
get_error_value()->end = end;
|
||||
if (!show_error_line()) {
|
||||
return false;
|
||||
}
|
||||
@@ -612,6 +613,10 @@ gb_internal void compiler_error(char const *fmt, ...) {
|
||||
}
|
||||
|
||||
|
||||
gb_internal void exit_with_errors(void) {
|
||||
print_all_errors();
|
||||
gb_exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -622,19 +627,99 @@ gb_internal int error_value_cmp(void const *a, void const *b) {
|
||||
}
|
||||
|
||||
gb_internal void print_all_errors(void) {
|
||||
auto const &escape_char = [](gbFile *f, u8 c) {
|
||||
switch (c) {
|
||||
case '\n': gb_file_write(f, "\\n", 2); break;
|
||||
case '"': gb_file_write(f, "\\\"", 2); break;
|
||||
case '\\': gb_file_write(f, "\\\\", 2); break;
|
||||
case '\b': gb_file_write(f, "\\b", 2); break;
|
||||
case '\f': gb_file_write(f, "\\f", 2); break;
|
||||
case '\r': gb_file_write(f, "\\r", 2); break;
|
||||
case '\t': gb_file_write(f, "\\t", 2); break;
|
||||
default:
|
||||
if ('\x00' <= c && c <= '\x1f') {
|
||||
gb_fprintf(f, "\\u%04x", c);
|
||||
} else {
|
||||
gb_file_write(f, &c, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
GB_ASSERT(any_errors());
|
||||
gbFile *f = gb_file_get_standard(gbFileStandard_Error);
|
||||
|
||||
array_sort(global_error_collector.error_values, error_value_cmp);
|
||||
|
||||
for_array(i, global_error_collector.error_values) {
|
||||
ErrorValue ev = global_error_collector.error_values[i];
|
||||
for (isize j = 0; j < ev.msgs.count; j++) {
|
||||
String msg = ev.msgs[j];
|
||||
gb_file_write(f, msg.text, msg.len);
|
||||
|
||||
if (terse_errors() && string_contains_char(msg, '\n')) {
|
||||
break;
|
||||
if (json_errors()) {
|
||||
gb_fprintf(f, "{\n");
|
||||
gb_fprintf(f, "\t\"error_count\": %td,\n", global_error_collector.error_values.count);
|
||||
gb_fprintf(f, "\t\"errors\": [\n");
|
||||
for_array(i, global_error_collector.error_values) {
|
||||
ErrorValue ev = global_error_collector.error_values[i];
|
||||
|
||||
gb_fprintf(f, "\t\t{\n");
|
||||
|
||||
gb_fprintf(f, "\t\t\t\"pos\": {\n");
|
||||
|
||||
if (ev.pos.file_id) {
|
||||
gb_fprintf(f, "\t\t\t\t\"file\": \"");
|
||||
String file = get_file_path_string(ev.pos.file_id);
|
||||
for (isize k = 0; k < file.len; k++) {
|
||||
escape_char(f, file.text[k]);
|
||||
}
|
||||
gb_fprintf(f, "\",\n");
|
||||
gb_fprintf(f, "\t\t\t\t\"line\": %d,\n", ev.pos.line);
|
||||
gb_fprintf(f, "\t\t\t\t\"column\": %d,\n", ev.pos.column);
|
||||
i32 end_column = gb_max(ev.end.column, ev.pos.column);
|
||||
gb_fprintf(f, "\t\t\t\t\"end_column\": %d\n", end_column);
|
||||
gb_fprintf(f, "\t\t\t},\n");
|
||||
}
|
||||
|
||||
gb_fprintf(f, "\t\t\t\"msgs\": [\n");
|
||||
|
||||
if (ev.msgs.count > 1) {
|
||||
gb_fprintf(f, "\t\t\t\t\"");
|
||||
|
||||
for (isize j = 1; j < ev.msgs.count; j++) {
|
||||
String msg = ev.msgs[j];
|
||||
for (isize k = 0; k < msg.len; k++) {
|
||||
u8 c = msg.text[k];
|
||||
if (c == '\n') {
|
||||
if (k+1 == msg.len && j+1 == ev.msgs.count) {
|
||||
// don't do the last one
|
||||
} else {
|
||||
gb_fprintf(f, "\",\n");
|
||||
gb_fprintf(f, "\t\t\t\t\"");
|
||||
}
|
||||
} else {
|
||||
escape_char(f, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
gb_fprintf(f, "\"\n");
|
||||
}
|
||||
gb_fprintf(f, "\t\t\t]\n");
|
||||
gb_fprintf(f, "\t\t}");
|
||||
if (i+1 != global_error_collector.error_values.count) {
|
||||
gb_fprintf(f, ",");
|
||||
}
|
||||
gb_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
gb_fprintf(f, "\t]\n");
|
||||
gb_fprintf(f, "}\n");
|
||||
} else {
|
||||
for_array(i, global_error_collector.error_values) {
|
||||
ErrorValue ev = global_error_collector.error_values[i];
|
||||
for (isize j = 0; j < ev.msgs.count; j++) {
|
||||
String msg = ev.msgs[j];
|
||||
gb_file_write(f, msg.text, msg.len);
|
||||
|
||||
if (terse_errors() && string_contains_char(msg, '\n')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1350,7 +1350,7 @@ gb_internal WORKER_TASK_PROC(lb_llvm_emit_worker_proc) {
|
||||
|
||||
if (LLVMTargetMachineEmitToFile(wd->target_machine, wd->m->mod, cast(char *)wd->filepath_obj.text, wd->code_gen_file_type, &llvm_error)) {
|
||||
gb_printf_err("LLVM Error: %s\n", llvm_error);
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
}
|
||||
debugf("Generated File: %.*s\n", LIT(wd->filepath_obj));
|
||||
return 0;
|
||||
@@ -1919,7 +1919,7 @@ verify
|
||||
gb_printf_err("LLVM Error: %s\n", llvm_error);
|
||||
}
|
||||
}
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@@ -2104,11 +2104,11 @@ gb_internal WORKER_TASK_PROC(lb_llvm_module_verification_worker_proc) {
|
||||
String filepath_ll = lb_filepath_ll_for_module(m);
|
||||
if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
|
||||
gb_printf_err("LLVM Error: %s\n", llvm_error);
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -2193,7 +2193,7 @@ gb_internal bool lb_llvm_object_generation(lbGenerator *gen, bool do_threading)
|
||||
|
||||
if (LLVMTargetMachineEmitToFile(m->target_machine, m->mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
|
||||
gb_printf_err("LLVM Error: %s\n", llvm_error);
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
return false;
|
||||
}
|
||||
debugf("Generated File: %.*s\n", LIT(filepath_obj));
|
||||
@@ -2393,7 +2393,7 @@ gb_internal void lb_generate_procedure(lbModule *m, lbProcedure *p) {
|
||||
gb_printf_err("LLVM Error: %s\n", llvm_error);
|
||||
}
|
||||
LLVMVerifyFunction(p->value, LLVMPrintMessageAction);
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2962,7 +2962,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
|
||||
String filepath_ll = lb_filepath_ll_for_module(m);
|
||||
if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
|
||||
gb_printf_err("LLVM Error: %s\n", llvm_error);
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
return false;
|
||||
}
|
||||
array_add(&gen->output_temp_paths, filepath_ll);
|
||||
|
||||
+11
-1
@@ -292,6 +292,7 @@ enum BuildFlagKind {
|
||||
BuildFlag_WarningsAsErrors,
|
||||
BuildFlag_TerseErrors,
|
||||
BuildFlag_VerboseErrors,
|
||||
BuildFlag_JsonErrors,
|
||||
BuildFlag_ErrorPosStyle,
|
||||
BuildFlag_MaxErrorCount,
|
||||
|
||||
@@ -480,6 +481,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
add_flag(&build_flags, BuildFlag_WarningsAsErrors, str_lit("warnings-as-errors"), BuildFlagParam_None, Command_all);
|
||||
add_flag(&build_flags, BuildFlag_TerseErrors, str_lit("terse-errors"), BuildFlagParam_None, Command_all);
|
||||
add_flag(&build_flags, BuildFlag_VerboseErrors, str_lit("verbose-errors"), BuildFlagParam_None, Command_all);
|
||||
add_flag(&build_flags, BuildFlag_JsonErrors, str_lit("json-errors"), BuildFlagParam_None, Command_all);
|
||||
add_flag(&build_flags, BuildFlag_ErrorPosStyle, str_lit("error-pos-style"), BuildFlagParam_String, Command_all);
|
||||
add_flag(&build_flags, BuildFlag_MaxErrorCount, str_lit("max-error-count"), BuildFlagParam_Integer, Command_all);
|
||||
|
||||
@@ -1184,6 +1186,10 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
build_context.terse_errors = false;
|
||||
break;
|
||||
|
||||
case BuildFlag_JsonErrors:
|
||||
build_context.json_errors = true;
|
||||
break;
|
||||
|
||||
case BuildFlag_ErrorPosStyle:
|
||||
GB_ASSERT(value.kind == ExactValue_String);
|
||||
|
||||
@@ -1398,7 +1404,7 @@ gb_internal void timings_export_all(Timings *t, Checker *c, bool timings_are_fin
|
||||
gbFileError err = gb_file_open_mode(&f, gbFileMode_Write, fileName);
|
||||
if (err != gbFileError_None) {
|
||||
gb_printf_err("Failed to export timings to: %s\n", fileName);
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
return;
|
||||
} else {
|
||||
gb_printf("\nExporting timings to '%s'... ", fileName);
|
||||
@@ -1984,6 +1990,10 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
print_usage_line(2, "Prints a terse error message without showing the code on that line and the location in that line.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-json-errors");
|
||||
print_usage_line(2, "Prints the error messages as json to stderr.");
|
||||
print_usage_line(0, "");
|
||||
|
||||
print_usage_line(1, "-error-pos-style:<string>");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-error-pos-style:unix file/path:45:3:");
|
||||
|
||||
+2
-2
@@ -1484,7 +1484,7 @@ gb_internal Token expect_token(AstFile *f, TokenKind kind) {
|
||||
String p = token_to_string(prev);
|
||||
syntax_error(f->curr_token, "Expected '%.*s', got '%.*s'", LIT(c), LIT(p));
|
||||
if (prev.kind == Token_EOF) {
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6177,7 +6177,7 @@ gb_internal ParseFileError process_imported_file(Parser *p, ImportedFile importe
|
||||
if (err == ParseFile_EmptyFile) {
|
||||
if (fi.fullpath == p->init_fullpath) {
|
||||
syntax_error(pos, "Initial file is empty - %.*s\n", LIT(p->init_fullpath));
|
||||
gb_exit(1);
|
||||
exit_with_errors();
|
||||
}
|
||||
} else {
|
||||
switch (err) {
|
||||
|
||||
Reference in New Issue
Block a user