mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-17 08:34:08 +00:00
Use UTF-8 command line on windows
This commit is contained in:
@@ -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<char> 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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
// #define GB_NO_DEFER
|
||||
#define GB_IMPLEMENTATION
|
||||
#include "gb/gb.h"
|
||||
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
|
||||
98
src/main.cpp
98
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, ...) {
|
||||
@@ -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<String> 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];
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user