Browse Source

Use UTF-8 command line on windows

Ginger Bill 8 years ago
parent
commit
bba088bee7
7 changed files with 162 additions and 42 deletions
  1. 5 2
      src/build_settings.cpp
  2. 4 3
      src/checker.cpp
  3. 69 1
      src/common.cpp
  4. 2 1
      src/ir.cpp
  5. 65 33
      src/main.cpp
  6. 4 2
      src/parser.cpp
  7. 13 0
      src/string.cpp

+ 5 - 2
src/build_settings.cpp

@@ -58,6 +58,8 @@ String odin_root_dir(void) {
 		}
 		}
 		array_resize(&path_buf, 2*path_buf.count + 300);
 		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);
 	tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
 
 
@@ -65,6 +67,7 @@ String odin_root_dir(void) {
 
 
 	GetModuleFileNameW(NULL, text, len);
 	GetModuleFileNameW(NULL, text, len);
 	path = string16_to_string(heap_allocator(), make_string16(text, len));
 	path = string16_to_string(heap_allocator(), make_string16(text, len));
+
 	for (i = path.len-1; i >= 0; i--) {
 	for (i = path.len-1; i >= 0; i--) {
 		u8 c = path[i];
 		u8 c = path[i];
 		if (c == '/' || c == '\\') {
 		if (c == '/' || c == '\\') {
@@ -92,7 +95,7 @@ String odin_root_dir(void) {
 	Array<char> path_buf;
 	Array<char> path_buf;
 	isize len, i;
 	isize len, i;
 	gbTempArenaMemory tmp;
 	gbTempArenaMemory tmp;
-	wchar_t *text;
+	u8 *text;
 
 
 	if (global_module_path_set) {
 	if (global_module_path_set) {
 		return global_module_path;
 		return global_module_path;
@@ -102,7 +105,7 @@ String odin_root_dir(void) {
 
 
 	len = 0;
 	len = 0;
 	for (;;) {
 	for (;;) {
-		int sz = path_buf.count;
+		u32 sz = path_buf.count;
 		int res = _NSGetExecutablePath(&path_buf[0], &sz);
 		int res = _NSGetExecutablePath(&path_buf[0], &sz);
 		if(res == 0) {
 		if(res == 0) {
 			len = sz;
 			len = sz;

+ 4 - 3
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);
 Type *       type_of_expr           (CheckerInfo *i, AstNode *expr);
 Entity *     entity_of_ident        (CheckerInfo *i, AstNode *identifier);
 Entity *     entity_of_ident        (CheckerInfo *i, AstNode *identifier);
 Entity *     implicit_entity_of_node(CheckerInfo *i, AstNode *clause);
 Entity *     implicit_entity_of_node(CheckerInfo *i, AstNode *clause);
-DeclInfo *   decl_info_of_entity    (CheckerInfo *i, Entity * e);
+Scope *      scope_of_node          (CheckerInfo *i, AstNode *node);
 DeclInfo *   decl_info_of_ident     (CheckerInfo *i, AstNode *ident);
 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);
 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
+// 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);
 Entity *current_scope_lookup_entity(Scope *s, String name);

+ 69 - 1
src/common.cpp

@@ -3,10 +3,13 @@
 #include <xmmintrin.h>
 #include <xmmintrin.h>
 #endif
 #endif
 
 
-// #define GB_NO_DEFER
 #define GB_IMPLEMENTATION
 #define GB_IMPLEMENTATION
 #include "gb/gb.h"
 #include "gb/gb.h"
 
 
+
+#include <wchar.h>
+#include <stdio.h>
+
 #include <math.h>
 #include <math.h>
 
 
 gbAllocator heap_allocator(void) {
 gbAllocator heap_allocator(void) {
@@ -240,3 +243,68 @@ f64 gb_sqrt(f64 x) {
 } while (0)
 } 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

+ 2 - 1
src/ir.cpp

@@ -7544,7 +7544,8 @@ void ir_gen_tree(irGen *s) {
 		String name = str_lit(IR_STARTUP_RUNTIME_PROC_NAME);
 		String name = str_lit(IR_STARTUP_RUNTIME_PROC_NAME);
 		Type *proc_type = make_type_proc(a, gb_alloc_item(a, Scope),
 		Type *proc_type = make_type_proc(a, gb_alloc_item(a, Scope),
 		                                 NULL, 0,
 		                                 NULL, 0,
-		                                 NULL, 0, false, ProcCC_Contextless);
+		                                 NULL, 0, false,
+		                                 ProcCC_Contextless);
 		AstNode *body = gb_alloc_item(a, AstNode);
 		AstNode *body = gb_alloc_item(a, AstNode);
 		Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
 		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);
 		irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);

+ 65 - 33
src/main.cpp

@@ -105,6 +105,31 @@ i32 system_exec_command_line_app(char *name, bool is_silent, char *fmt, ...) {
 
 
 
 
 
 
+Array<String> setup_args(int argc, char **argv) {
+	Array<String> 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, ...) {
 void print_usage_line(i32 indent, char *fmt, ...) {
@@ -118,10 +143,10 @@ void print_usage_line(i32 indent, char *fmt, ...) {
 	gb_printf_err("\n");
 	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(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(0, "Commands:");
 	print_usage_line(1, "build        compile .odin file as executable");
 	print_usage_line(1, "build        compile .odin file as executable");
 	print_usage_line(1, "build_dll    compile .odin file as dll");
 	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");
 	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;
 		return 1;
 	}
 	}
 
 
 	Timings timings = {0};
 	Timings timings = {0};
 	timings_init(&timings, str_lit("Total Time"), 128);
 	timings_init(&timings, str_lit("Total Time"), 128);
-	// defer (timings_destroy(&timings));
+	defer (timings_destroy(&timings));
 	init_string_buffer_memory();
 	init_string_buffer_memory();
 	init_scratch_memory(gb_megabytes(10));
 	init_scratch_memory(gb_megabytes(10));
 	init_global_error_collector();
 	init_global_error_collector();
 
 
+	Array<String> args = setup_args(arg_count, arg_ptr);
+
+
 #if 1
 #if 1
 	init_build_context();
 	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();
 	init_universal_scope();
 
 
-	char *init_filename = NULL;
+	String init_filename = {};
 	bool run_output = false;
 	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;
 			return 1;
 		}
 		}
-		init_filename = argv[2];
+		init_filename = args[2];
 		run_output = true;
 		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;
 			return 1;
 		}
 		}
-		init_filename = argv[2];
+		init_filename = args[2];
 		build_context.is_dll = true;
 		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;
 			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;
 			return 1;
 		}
 		}
 
 
-		init_filename = argv[2];
+		init_filename = args[2];
 		build_context.generate_docs = true;
 		build_context.generate_docs = true;
 		#if 1
 		#if 1
 		print_usage_line(0, "Documentation generation is not yet supported");
 		print_usage_line(0, "Documentation generation is not yet supported");
 		return 1;
 		return 1;
 		#endif
 		#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;
 		return 0;
 	} else {
 	} else {
-		usage(argv[0]);
+		usage(args[0]);
 		return 1;
 		return 1;
 	}
 	}
 
 
@@ -199,7 +231,7 @@ int main(int argc, char **argv) {
 	if (!init_parser(&parser)) {
 	if (!init_parser(&parser)) {
 		return 1;
 		return 1;
 	}
 	}
-	// defer (destroy_parser(&parser));
+	defer (destroy_parser(&parser));
 
 
 	if (parse_files(&parser, init_filename) != ParseFile_None) {
 	if (parse_files(&parser, init_filename) != ParseFile_None) {
 		return 1;
 		return 1;
@@ -216,7 +248,7 @@ int main(int argc, char **argv) {
 	Checker checker = {0};
 	Checker checker = {0};
 
 
 	init_checker(&checker, &parser);
 	init_checker(&checker, &parser);
-	// defer (destroy_checker(&checker));
+	defer (destroy_checker(&checker));
 
 
 	check_parsed_files(&checker);
 	check_parsed_files(&checker);
 
 
@@ -239,7 +271,7 @@ int main(int argc, char **argv) {
 	if (!ir_gen_init(&ir_gen, &checker)) {
 	if (!ir_gen_init(&ir_gen, &checker)) {
 		return 1;
 		return 1;
 	}
 	}
-	// defer (ssa_gen_destroy(&ir_gen));
+	defer (ir_gen_destroy(&ir_gen));
 
 
 	timings_start_section(&timings, str_lit("llvm ir gen"));
 	timings_start_section(&timings, str_lit("llvm ir gen"));
 	ir_gen_tree(&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"));
 		timings_start_section(&timings, str_lit("msvc-link"));
 
 
 		gbString lib_str = gb_string_make(heap_allocator(), "");
 		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};
 		char lib_str_buf[1024] = {0};
 		for_array(i, ir_gen.module.foreign_library_paths) {
 		for_array(i, ir_gen.module.foreign_library_paths) {
 			String lib = ir_gen.module.foreign_library_paths[i];
 			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"));
 		timings_start_section(&timings, str_lit("ld-link"));
 
 
 		gbString lib_str = gb_string_make(heap_allocator(), "");
 		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};
 		char lib_str_buf[1024] = {0};
 		for_array(i, ir_gen.module.foreign_library_paths) {
 		for_array(i, ir_gen.module.foreign_library_paths) {
 			String lib = ir_gen.module.foreign_library_paths[i];
 			String lib = ir_gen.module.foreign_library_paths[i];

+ 4 - 2
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);
 	String init_fullpath = make_string_c(fullpath_str);
 	TokenPos init_pos = {};
 	TokenPos init_pos = {};
 	ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos};
 	ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos};

+ 13 - 0
src/string.cpp

@@ -64,6 +64,17 @@ gb_inline String16 make_string16(wchar_t *text, isize len) {
 	return s;
 	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) {
 gb_inline String make_string_c(char *text) {
 	return make_string(cast(u8 *)cast(void *)text, gb_strlen(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);
 	return make_string16(text, len-1);
 }
 }
 
 
+
 String string16_to_string(gbAllocator a, String16 s) {
 String string16_to_string(gbAllocator a, String16 s) {
 	int len, len1;
 	int len, len1;
 	u8 *text;
 	u8 *text;
@@ -319,6 +331,7 @@ String string16_to_string(gbAllocator a, String16 s) {
 	if (len == 0) {
 	if (len == 0) {
 		return make_string(NULL, 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);
 	text = gb_alloc_array(a, u8, len+1);