diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 99ab55d1c..5b96cf07a 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -58,6 +58,8 @@ String odin_root_dir(void) { } array_resize(&path_buf, 2*path_buf.count + 300); } + len += 1; // NOTE(bill): It needs an extra 1 for some reason + tmp = gb_temp_arena_memory_begin(&string_buffer_arena); @@ -65,6 +67,7 @@ String odin_root_dir(void) { GetModuleFileNameW(NULL, text, len); path = string16_to_string(heap_allocator(), make_string16(text, len)); + for (i = path.len-1; i >= 0; i--) { u8 c = path[i]; if (c == '/' || c == '\\') { @@ -92,7 +95,7 @@ String odin_root_dir(void) { Array path_buf; isize len, i; gbTempArenaMemory tmp; - wchar_t *text; + u8 *text; if (global_module_path_set) { return global_module_path; @@ -102,7 +105,7 @@ String odin_root_dir(void) { len = 0; for (;;) { - int sz = path_buf.count; + u32 sz = path_buf.count; int res = _NSGetExecutablePath(&path_buf[0], &sz); if(res == 0) { len = sz; diff --git a/src/checker.cpp b/src/checker.cpp index c2318f9d2..a912c6a59 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -314,11 +314,12 @@ TypeAndValue type_and_value_of_expr (CheckerInfo *i, AstNode *expr); Type * type_of_expr (CheckerInfo *i, AstNode *expr); Entity * entity_of_ident (CheckerInfo *i, AstNode *identifier); Entity * implicit_entity_of_node(CheckerInfo *i, AstNode *clause); -DeclInfo * decl_info_of_entity (CheckerInfo *i, Entity * e); -DeclInfo * decl_info_of_ident (CheckerInfo *i, AstNode *ident); -AstFile * ast_file_of_filename (CheckerInfo *i, String filename); Scope * scope_of_node (CheckerInfo *i, AstNode *node); -isize type_info_index (CheckerInfo *i, Type *type); // Only to use once checking is done +DeclInfo * decl_info_of_ident (CheckerInfo *i, AstNode *ident); +DeclInfo * decl_info_of_entity (CheckerInfo *i, Entity * e); +AstFile * ast_file_of_filename (CheckerInfo *i, String filename); +// IMPORTANT: Only to use once checking is done +isize type_info_index (CheckerInfo *i, Type * type); Entity *current_scope_lookup_entity(Scope *s, String name); diff --git a/src/common.cpp b/src/common.cpp index 0c096a40d..8ad21a2d6 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -3,10 +3,13 @@ #include #endif -// #define GB_NO_DEFER #define GB_IMPLEMENTATION #include "gb/gb.h" + +#include +#include + #include gbAllocator heap_allocator(void) { @@ -240,3 +243,68 @@ f64 gb_sqrt(f64 x) { } while (0) + +#if defined(GB_SYSTEM_WINDOWS) + +wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc) { + u32 i, j; + + u32 len = string16_len(cmd_line); + i = ((len+2)/2)*gb_size_of(void *) + gb_size_of(void *); + + wchar_t **argv = cast(wchar_t **)GlobalAlloc(GMEM_FIXED, i + (len+2)*gb_size_of(wchar_t)); + wchar_t *_argv = cast(wchar_t *)((cast(u8 *)argv)+i); + + u32 argc = 0; + argv[argc] = _argv; + bool in_quote = false; + bool in_text = false; + bool in_space = true; + i = 0; + j = 0; + + for (;;) { + wchar_t a = cmd_line[i]; + if (a == 0) { + break; + } + if (in_quote) { + if (a == '\"') { + in_quote = false; + } else { + _argv[j++] = a; + } + } else { + switch (a) { + case '\"': + in_quote = true; + in_text = true; + if (in_space) argv[argc++] = _argv+j; + in_space = false; + break; + case ' ': + case '\t': + case '\n': + case '\r': + if (in_text) _argv[j++] = '\0'; + in_text = false; + in_space = true; + break; + default: + in_text = true; + if (in_space) argv[argc++] = _argv+j; + _argv[j++] = a; + in_space = false; + break; + } + } + i++; + } + _argv[j] = '\0'; + argv[argc] = NULL; + + if (_argc) *_argc = argc; + return argv; +} + +#endif diff --git a/src/ir.cpp b/src/ir.cpp index dc1bd2142..b2a6b9579 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7544,7 +7544,8 @@ void ir_gen_tree(irGen *s) { String name = str_lit(IR_STARTUP_RUNTIME_PROC_NAME); Type *proc_type = make_type_proc(a, gb_alloc_item(a, Scope), NULL, 0, - NULL, 0, false, ProcCC_Contextless); + NULL, 0, false, + ProcCC_Contextless); AstNode *body = gb_alloc_item(a, AstNode); Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0); irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name); diff --git a/src/main.cpp b/src/main.cpp index cc6472561..d838ce908 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -105,6 +105,31 @@ i32 system_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) { +Array setup_args(int argc, char **argv) { + Array args = {}; + gbAllocator a = heap_allocator(); + int i; + +#if defined(GB_SYSTEM_WINDOWS) + int wargc = 0; + wchar_t **wargv = command_line_to_wargv(GetCommandLineW(), &wargc); + array_init(&args, a, wargc); + for (i = 0; i < wargc; i++) { + wchar_t *warg = wargv[i]; + isize wlen = string16_len(warg); + String16 wstr = make_string16(warg, wlen); + array_add(&args, string16_to_string(a, wstr)); + } + +#else + array_init(&args, a, argc); + for (i = 0; i < argc; i++) { + array_add(&args, make_string_c(argv[i])); + } +#endif + return args; +} + void print_usage_line(i32 indent, char *fmt, ...) { @@ -118,10 +143,10 @@ void print_usage_line(i32 indent, char *fmt, ...) { gb_printf_err("\n"); } -void usage(char *argv0) { - print_usage_line(0, "%s is a tool for managing Odin source code", argv0); +void usage(String argv0) { + print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(argv0)); print_usage_line(0, "Usage:"); - print_usage_line(1, "%s command [arguments]", argv0); + print_usage_line(1, "%.*s command [arguments]", LIT(argv0)); print_usage_line(0, "Commands:"); print_usage_line(1, "build compile .odin file as executable"); print_usage_line(1, "build_dll compile .odin file as dll"); @@ -130,64 +155,71 @@ void usage(char *argv0) { print_usage_line(1, "version print version"); } -int main(int argc, char **argv) { - if (argc < 2) { - usage(argv[0]); +int main(int arg_count, char **arg_ptr) { + if (arg_count < 2) { + usage(make_string_c(arg_ptr[0])); return 1; } Timings timings = {0}; timings_init(&timings, str_lit("Total Time"), 128); - // defer (timings_destroy(&timings)); + defer (timings_destroy(&timings)); init_string_buffer_memory(); init_scratch_memory(gb_megabytes(10)); init_global_error_collector(); + Array args = setup_args(arg_count, arg_ptr); + + #if 1 init_build_context(); + if (build_context.word_size == 4) { + print_usage_line(0, "%s 32-bit is not yet supported", args[0]); + return 1; + } + init_universal_scope(); - char *init_filename = NULL; + String init_filename = {}; bool run_output = false; - String arg1 = make_string_c(argv[1]); - if (arg1 == "run") { - if (argc != 3) { - usage(argv[0]); + if (args[1] == "run") { + if (args.count != 3) { + usage(args[0]); return 1; } - init_filename = argv[2]; + init_filename = args[2]; run_output = true; - } else if (arg1 == "build_dll") { - if (argc != 3) { - usage(argv[0]); + } else if (args[1] == "build_dll") { + if (args.count != 3) { + usage(args[0]); return 1; } - init_filename = argv[2]; + init_filename = args[2]; build_context.is_dll = true; - } else if (arg1 == "build") { - if (argc != 3) { - usage(argv[0]); + } else if (args[1] == "build") { + if (args.count != 3) { + usage(args[0]); return 1; } - init_filename = argv[2]; - } else if (arg1 == "docs") { - if (argc != 3) { - usage(argv[0]); + init_filename = args[2]; + } else if (args[1] == "docs") { + if (args.count != 3) { + usage(args[0]); return 1; } - init_filename = argv[2]; + init_filename = args[2]; build_context.generate_docs = true; #if 1 print_usage_line(0, "Documentation generation is not yet supported"); return 1; #endif - } else if (arg1 == "version") { - gb_printf("%s version %.*s\n", argv[0], LIT(build_context.ODIN_VERSION)); + } else if (args[1] == "version") { + gb_printf("%s version %.*s\n", args[0], LIT(build_context.ODIN_VERSION)); return 0; } else { - usage(argv[0]); + usage(args[0]); return 1; } @@ -199,7 +231,7 @@ int main(int argc, char **argv) { if (!init_parser(&parser)) { return 1; } - // defer (destroy_parser(&parser)); + defer (destroy_parser(&parser)); if (parse_files(&parser, init_filename) != ParseFile_None) { return 1; @@ -216,7 +248,7 @@ int main(int argc, char **argv) { Checker checker = {0}; init_checker(&checker, &parser); - // defer (destroy_checker(&checker)); + defer (destroy_checker(&checker)); check_parsed_files(&checker); @@ -239,7 +271,7 @@ int main(int argc, char **argv) { if (!ir_gen_init(&ir_gen, &checker)) { return 1; } - // defer (ssa_gen_destroy(&ir_gen)); + defer (ir_gen_destroy(&ir_gen)); timings_start_section(&timings, str_lit("llvm ir gen")); ir_gen_tree(&ir_gen); @@ -323,7 +355,7 @@ int main(int argc, char **argv) { timings_start_section(&timings, str_lit("msvc-link")); gbString lib_str = gb_string_make(heap_allocator(), ""); - // defer (gb_string_free(lib_str)); + defer (gb_string_free(lib_str)); char lib_str_buf[1024] = {0}; for_array(i, ir_gen.module.foreign_library_paths) { String lib = ir_gen.module.foreign_library_paths[i]; @@ -385,7 +417,7 @@ int main(int argc, char **argv) { timings_start_section(&timings, str_lit("ld-link")); gbString lib_str = gb_string_make(heap_allocator(), ""); - // defer (gb_string_free(lib_str)); + defer (gb_string_free(lib_str)); char lib_str_buf[1024] = {0}; for_array(i, ir_gen.module.foreign_library_paths) { String lib = ir_gen.module.foreign_library_paths[i]; diff --git a/src/parser.cpp b/src/parser.cpp index 78a17257a..a023bccd5 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4664,8 +4664,10 @@ void parse_file(Parser *p, AstFile *f) { -ParseFileError parse_files(Parser *p, char *init_filename) { - char *fullpath_str = gb_path_get_full_name(heap_allocator(), init_filename); +ParseFileError parse_files(Parser *p, String init_filename) { + GB_ASSERT(init_filename.text[init_filename.len] == 0); + + char *fullpath_str = gb_path_get_full_name(heap_allocator(), cast(char *)&init_filename[0]); String init_fullpath = make_string_c(fullpath_str); TokenPos init_pos = {}; ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos}; diff --git a/src/string.cpp b/src/string.cpp index f2ba05689..1795b411d 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -64,6 +64,17 @@ gb_inline String16 make_string16(wchar_t *text, isize len) { return s; } +isize string16_len(wchar_t *s) { + if (s == NULL) { + return 0; + } + wchar_t *p = s; + while (*p) { + p++; + } + return p - s; +} + gb_inline String make_string_c(char *text) { return make_string(cast(u8 *)cast(void *)text, gb_strlen(text)); @@ -307,6 +318,7 @@ String16 string_to_string16(gbAllocator a, String s) { return make_string16(text, len-1); } + String string16_to_string(gbAllocator a, String16 s) { int len, len1; u8 *text; @@ -319,6 +331,7 @@ String string16_to_string(gbAllocator a, String16 s) { if (len == 0) { return make_string(NULL, 0); } + len += 1; // NOTE(bill): It needs an extra 1 for some reason text = gb_alloc_array(a, u8, len+1);