diff --git a/core/_preload.odin b/core/_preload.odin index 2e29ecaa8..3c1b7569d 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -473,6 +473,9 @@ new_clone :: inline proc(data: $T, loc := #caller_location) -> ^T { free_string :: proc(str: string, loc := #caller_location) { free_ptr(raw.data(str), loc); } +free_cstring :: proc(str: cstring, loc := #caller_location) { + free_ptr((^byte)(str), loc); +} free_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) { free_ptr(raw.data(array), loc); } @@ -486,7 +489,9 @@ free_map :: proc(m: $T/map[$K]$V, loc := #caller_location) { } free :: proc[ - free_ptr, free_string, free_dynamic_array, free_slice, free_map, + free_ptr, + free_string, free_cstring, + free_dynamic_array, free_slice, free_map, ]; diff --git a/core/opengl.odin b/core/opengl.odin index 3fa63ec32..6a2794d1f 100644 --- a/core/opengl.odin +++ b/core/opengl.odin @@ -31,7 +31,7 @@ foreign lib { Color3f :: proc(r, g, b: f32) ---; Vertex3f :: proc(x, y, z: f32) ---; GetError :: proc() -> i32 ---; - GetString :: proc(name: i32) -> ^u8 ---; + GetString :: proc(name: i32) -> cstring ---; GetIntegerv :: proc(name: i32, v: ^i32) ---; TexCoord2f :: proc(x, y: f32) ---; TexImage2D :: proc(target, level, internal_format: i32, @@ -40,9 +40,7 @@ foreign lib { } -_string_data :: inline proc(s: string) -> ^u8 do return &s[0]; - -_libgl := win32.load_library_a(_string_data("opengl32.dll\x00")); +_libgl := win32.load_library_a("opengl32.dll"); get_gl_proc_address :: proc(name: string) -> rawptr { if name[len(name)-1] == 0 { @@ -50,9 +48,9 @@ get_gl_proc_address :: proc(name: string) -> rawptr { } // NOTE(bill): null terminated assert((&name[0] + len(name))^ == 0); - res := wgl.get_gl_proc_address(&name[0]); + res := wgl.get_gl_proc_address(cstring(&name[0])); if res == nil { - res = win32.get_proc_address(_libgl, &name[0]); + res = win32.get_proc_address(_libgl, cstring(&name[0])); } return rawptr(res); } @@ -79,7 +77,7 @@ get_gl_proc_address :: proc(name: string) -> rawptr { EnableVertexAttribArray: proc "c" (index: u32); CreateShader: proc "c" (shader_type: i32) -> u32; - ShaderSource: proc "c" (shader: u32, count: u32, str: ^^u8, length: ^i32); + ShaderSource: proc "c" (shader: u32, count: u32, str: ^cstring, length: ^i32); CompileShader: proc "c" (shader: u32); CreateProgram: proc "c" () -> u32; AttachShader: proc "c" (program, shader: u32); @@ -92,8 +90,8 @@ get_gl_proc_address :: proc(name: string) -> rawptr { GetShaderiv: proc "c" (shader: u32, pname: i32, params: ^i32); GetProgramiv: proc "c" (program: u32, pname: i32, params: ^i32); - GetShaderInfoLog: proc "c" (shader: u32, max_length: u32, length: ^u32, info_long: ^u8); - GetProgramInfoLog: proc "c" (program: u32, max_length: u32, length: ^u32, info_long: ^u8); + GetShaderInfoLog: proc "c" (shader: u32, max_length: u32, length: ^u32, info_long: cstring); + GetProgramInfoLog: proc "c" (program: u32, max_length: u32, length: ^u32, info_long: cstring); ActiveTexture: proc "c" (texture: i32); GenerateMipmap: proc "c" (target: i32); @@ -116,7 +114,7 @@ get_gl_proc_address :: proc(name: string) -> rawptr { Uniform4f: proc "c" (loc: i32, v0, v1, v2, v3: f32); UniformMatrix4fv: proc "c" (loc: i32, count: u32, transpose: i32, value: ^f32); - GetUniformLocation: proc "c" (program: u32, name: ^u8) -> i32; + GetUniformLocation: proc "c" (program: u32, name: cstring) -> i32; init :: proc() { diff --git a/core/os_essence.odin b/core/os_essence.odin index 22a78c490..1973500bb 100644 --- a/core/os_essence.odin +++ b/core/os_essence.odin @@ -23,10 +23,10 @@ OS_Node_Information :: struct { foreign api { @(link_name="OSHelloWorld") os_hello_world :: proc() ---; - @(link_name="OSPrintDirect") os_print_direct :: proc(string: ^byte, length: int) ---; + @(link_name="OSPrintDirect") os_print_direct :: proc(str: cstring, length: int) ---; @(link_name="OSHeapAllocate") os_heap_allocate :: proc(bytes: int, zero: bool) -> rawptr ---; @(link_name="OSHeapFree") os_heap_free :: proc(address: rawptr) ---; - @(link_name="OSOpenNode") os_open_node :: proc(path: ^byte, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---; + @(link_name="OSOpenNode") os_open_node :: proc(path: cstring, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---; @(link_name="OSResizeFile") os_resize_file :: proc(handle: Handle, new_size: u64) -> Errno ---; @(link_name="OSCloseHandle") os_close_handle :: proc(handle: Handle) ---; @(link_name="OSWriteFileSync") os_write_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---; diff --git a/core/os_linux.odin b/core/os_linux.odin index f275d5839..1bfb3c428 100644 --- a/core/os_linux.odin +++ b/core/os_linux.odin @@ -122,34 +122,33 @@ W_OK :: 2; // Test for write permission R_OK :: 4; // Test for read permission foreign libc { - @(link_name="open") _unix_open :: proc(path: ^byte, mode: int) -> Handle ---; + @(link_name="open") _unix_open :: proc(path: cstring, mode: int) -> Handle ---; @(link_name="close") _unix_close :: proc(fd: Handle) -> i32 ---; @(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: int) -> int ---; @(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: int) -> int ---; @(link_name="lseek64") _unix_seek :: proc(fd: Handle, offset: i64, whence: i32) -> i64 ---; @(link_name="gettid") _unix_gettid :: proc() -> u64 ---; - @(link_name="stat") _unix_stat :: proc(path: ^byte, stat: ^Stat) -> i32 ---; - @(link_name="access") _unix_access :: proc(path: ^byte, mask: int) -> i32 ---; + @(link_name="stat") _unix_stat :: proc(path: cstring, stat: ^Stat) -> i32 ---; + @(link_name="access") _unix_access :: proc(path: cstring, mask: int) -> i32 ---; @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---; @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---; @(link_name="free") _unix_free :: proc(ptr: rawptr) ---; @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---; - @(link_name="getenv") _unix_getenv :: proc(^byte) -> ^byte ---; + @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---; @(link_name="exit") _unix_exit :: proc(status: int) ---; } foreign dl { - @(link_name="dlopen") _unix_dlopen :: proc(filename: ^byte, flags: int) -> rawptr ---; - @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^byte) -> rawptr ---; + @(link_name="dlopen") _unix_dlopen :: proc(filename: cstring, flags: int) -> rawptr ---; + @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr ---; @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> int ---; - @(link_name="dlerror") _unix_dlerror :: proc() -> ^byte ---; + @(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---; } // TODO(zangent): Change this to just `open` when Bill fixes overloading. open_simple :: proc(path: string, mode: int) -> (Handle, Errno) { - - cstr := strings.new_c_string(path); + cstr := strings.new_cstring(path); handle := _unix_open(cstr, mode); free(cstr); if(handle == -1) { @@ -201,7 +200,7 @@ last_write_time_by_name :: proc(name: string) -> File_Time {} */ stat :: inline proc(path: string) -> (Stat, int) { - cstr := strings.new_c_string(path); + cstr := strings.new_cstring(path); defer free(cstr); s: Stat; @@ -210,7 +209,7 @@ stat :: inline proc(path: string) -> (Stat, int) { } access :: inline proc(path: string, mask: int) -> bool { - cstr := strings.new_c_string(path); + cstr := strings.new_cstring(path); defer free(cstr); return _unix_access(cstr, mask) == 0; } @@ -229,13 +228,13 @@ heap_free :: proc(ptr: rawptr) { } getenv :: proc(name: string) -> (string, bool) { - path_str := strings.new_c_string(name); + path_str := strings.new_cstring(name); defer free(path_str); cstr := _unix_getenv(path_str); if cstr == nil { return "", false; } - return strings.to_odin_string(cstr), true; + return string(cstr), true; } exit :: proc(code: int) { @@ -248,14 +247,14 @@ current_thread_id :: proc() -> int { } dlopen :: inline proc(filename: string, flags: int) -> rawptr { - cstr := strings.new_c_string(filename); + cstr := strings.new_cstring(filename); defer free(cstr); handle := _unix_dlopen(cstr, flags); return handle; } dlsym :: inline proc(handle: rawptr, symbol: string) -> rawptr { assert(handle != nil); - cstr := strings.new_c_string(symbol); + cstr := strings.new_cstring(symbol); defer free(cstr); proc_handle := _unix_dlsym(handle, cstr); return proc_handle; @@ -265,14 +264,14 @@ dlclose :: inline proc(handle: rawptr) -> bool { return _unix_dlclose(handle) == 0; } dlerror :: proc() -> string { - return strings.to_odin_string(_unix_dlerror()); + return string(_unix_dlerror()); } _alloc_command_line_arguments :: proc() -> []string { args := make([]string, __argc__); for i in 0..__argc__ { - args[i] = strings.to_odin_string((__argv__+i)^); + args[i] = string((__argv__+i)^); } return args; } diff --git a/core/os_windows.odin b/core/os_windows.odin index e3fc4989d..62f35740d 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -98,7 +98,7 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn buf: [300]byte; copy(buf[..], cast([]byte)path); - handle := Handle(win32.create_file_a(&buf[0], access, share_mode, sa, create_mode, win32.FILE_ATTRIBUTE_NORMAL, nil)); + handle := Handle(win32.create_file_a(cstring(&buf[0]), access, share_mode, sa, create_mode, win32.FILE_ATTRIBUTE_NORMAL, nil)); if handle != INVALID_HANDLE do return handle, ERROR_NONE; err := Errno(win32.get_last_error()); @@ -219,7 +219,7 @@ last_write_time_by_name :: proc(name: string) -> File_Time { copy(buf[..], cast([]byte)name); - if win32.get_file_attributes_ex_a(&buf[0], win32.GetFileExInfoStandard, &data) { + if win32.get_file_attributes_ex_a(cstring(&buf[0]), win32.GetFileExInfoStandard, &data) { last_write_time = data.last_write_time; } @@ -272,7 +272,7 @@ _alloc_command_line_arguments :: proc() -> []string { buf := make([]byte, olen); n := win32.wide_char_to_multi_byte(win32.CP_UTF8, 0, wc_str, -1, - &buf[0], olen, nil, nil); + cstring(&buf[0]), olen, nil, nil); if n > 0 { n -= 1; } diff --git a/core/os_x.odin b/core/os_x.odin index 9a0e28761..67abf59b5 100644 --- a/core/os_x.odin +++ b/core/os_x.odin @@ -122,34 +122,34 @@ X_OK :: 1; // Test for execute permission F_OK :: 0; // Test for file existance foreign libc { - @(link_name="open") _unix_open :: proc(path: ^byte, mode: int) -> Handle ---; + @(link_name="open") _unix_open :: proc(path: cstring, mode: int) -> Handle ---; @(link_name="close") _unix_close :: proc(handle: Handle) ---; @(link_name="read") _unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int ---; @(link_name="write") _unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int ---; @(link_name="lseek") _unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int ---; @(link_name="gettid") _unix_gettid :: proc() -> u64 ---; - @(link_name="stat") _unix_stat :: proc(path: ^byte, stat: ^Stat) -> int ---; - @(link_name="access") _unix_access :: proc(path: ^byte, mask: int) -> int ---; + @(link_name="stat") _unix_stat :: proc(path: cstring, stat: ^Stat) -> int ---; + @(link_name="access") _unix_access :: proc(path: cstring, mask: int) -> int ---; @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---; @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---; @(link_name="free") _unix_free :: proc(ptr: rawptr) ---; @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---; - @(link_name="getenv") _unix_getenv :: proc(^byte) -> ^byte ---; + @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---; @(link_name="exit") _unix_exit :: proc(status: int) ---; } foreign dl { - @(link_name="dlopen") _unix_dlopen :: proc(filename: ^byte, flags: int) -> rawptr ---; - @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: ^byte) -> rawptr ---; + @(link_name="dlopen") _unix_dlopen :: proc(filename: cstring, flags: int) -> rawptr ---; + @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr ---; @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> int ---; - @(link_name="dlerror") _unix_dlerror :: proc() -> ^byte ---; + @(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---; } // TODO(zangent): Change this to just `open` when Bill fixes overloading. open_simple :: proc(path: string, mode: int) -> (Handle, Errno) { - cstr := strings.new_c_string(path); + cstr := strings.new_cstring(path); defer free(cstr); handle := _unix_open(cstr, mode); if handle == -1 { @@ -218,14 +218,14 @@ last_write_time_by_name :: proc(name: string) -> File_Time {} stat :: inline proc(path: string) -> (Stat, bool) { s: Stat; - cstr := strings.new_c_string(path); + cstr := strings.new_cstring(path); defer free(cstr); ret_int := _unix_stat(cstr, &s); return s, ret_int==0; } access :: inline proc(path: string, mask: int) -> bool { - cstr := strings.new_c_string(path); + cstr := strings.new_cstring(path); defer free(cstr); return _unix_access(cstr, mask) == 0; } @@ -242,13 +242,13 @@ heap_free :: inline proc(ptr: rawptr) { } getenv :: proc(name: string) -> (string, bool) { - path_str := strings.new_c_string(name); + path_str := strings.new_cstring(name); defer free(path_str); cstr := _unix_getenv(path_str); if cstr == nil { return "", false; } - return strings.to_odin_string(cstr), true; + return string(cstr), true; } exit :: inline proc(code: int) { @@ -262,14 +262,14 @@ current_thread_id :: proc() -> int { } dlopen :: inline proc(filename: string, flags: int) -> rawptr { - cstr := strings.new_c_string(filename); + cstr := strings.new_cstring(filename); defer free(cstr); handle := _unix_dlopen(cstr, flags); return handle; } dlsym :: inline proc(handle: rawptr, symbol: string) -> rawptr { assert(handle != nil); - cstr := strings.new_c_string(symbol); + cstr := strings.new_cstring(symbol); defer free(cstr); proc_handle := _unix_dlsym(handle, cstr); return proc_handle; @@ -279,14 +279,14 @@ dlclose :: inline proc(handle: rawptr) -> bool { return _unix_dlclose(handle) == 0; } dlerror :: proc() -> string { - return strings.to_odin_string(_unix_dlerror()); + return string(_unix_dlerror()); } _alloc_command_line_arguments :: proc() -> []string { args := make([]string, __argc__); for i in 0..__argc__ { - args[i] = strings.to_odin_string((__argv__+i)^); + args[i] = string((__argv__+i)^); } return args; } diff --git a/core/raw.odin b/core/raw.odin index 9a9f9a77b..47ee64632 100644 --- a/core/raw.odin +++ b/core/raw.odin @@ -8,6 +8,10 @@ String :: struct { len: int, } +Cstring :: struct { + data: ^byte, +} + Slice :: struct { data: rawptr, len: int, diff --git a/core/strings.odin b/core/strings.odin index bc76e78d0..7a26dee0c 100644 --- a/core/strings.odin +++ b/core/strings.odin @@ -7,18 +7,16 @@ new_string :: proc(s: string) -> string { return string(c[..len(s)]); } -new_c_string :: proc(s: string) -> ^byte { +new_cstring :: proc(s: string) -> cstring { c := make([]byte, len(s)+1); copy(c, cast([]byte)s); c[len(s)] = 0; - return &c[0]; + return cstring(&c[0]); } -to_odin_string :: proc(str: ^byte) -> string { +to_odin_string :: proc(str: cstring) -> string { if str == nil do return ""; - end := str; - for end^ != 0 do end+=1; - return string(mem.slice_ptr(str, end-str)); + return string(str); } contains_rune :: proc(s: string, r: rune) -> int { diff --git a/core/sys/wgl.odin b/core/sys/wgl.odin index db9e1f7b8..b95fba414 100644 --- a/core/sys/wgl.odin +++ b/core/sys/wgl.odin @@ -55,7 +55,7 @@ Glyph_Metrics_Float :: struct { Create_Context_Attribs_ARB_Type :: #type proc "c" (hdc: Hdc, h_share_context: rawptr, attribList: ^i32) -> Hglrc; Choose_Pixel_Format_ARB_Type :: #type proc "c" (hdc: Hdc, attrib_i_list: ^i32, attrib_f_list: ^f32, max_formats: u32, formats: ^i32, num_formats : ^u32) -> Bool; Swap_Interval_EXT_Type :: #type proc "c" (interval: i32) -> bool; -Get_Extensions_String_ARB_Type :: #type proc "c" (Hdc) -> ^byte; +Get_Extensions_String_ARB_Type :: #type proc "c" (Hdc) -> cstring; // Procedures create_context_attribs_arb: Create_Context_Attribs_ARB_Type; @@ -72,7 +72,7 @@ foreign opengl32 { make_current :: proc(hdc: Hdc, hglrc: Hglrc) -> Bool ---; @(link_name="wglGetProcAddress") - get_gl_proc_address :: proc(c_str: ^byte) -> rawptr ---; + get_gl_proc_address :: proc(c_str: cstring) -> rawptr ---; @(link_name="wglDeleteContext") delete_context :: proc(hglrc: Hglrc) -> Bool ---; diff --git a/core/sys/windows.odin b/core/sys/windows.odin index 40abc8f8c..d8269667d 100644 --- a/core/sys/windows.odin +++ b/core/sys/windows.odin @@ -28,6 +28,8 @@ Long_Ptr :: distinct int; Bool :: distinct b32; +Wstring :: ^u16; + Point :: struct { x, y: i32, } @@ -40,7 +42,7 @@ Wnd_Class_Ex_A :: struct { icon: Hicon, cursor: Hcursor, background: Hbrush, - menu_name, class_name: ^byte, + menu_name, class_name: cstring, sm: Hicon, } @@ -52,7 +54,7 @@ Wnd_Class_Ex_W :: struct { icon: Hicon, cursor: Hcursor, background: Hbrush, - menu_name, class_name: ^u16, + menu_name, class_name: Wstring, sm: Hicon, } @@ -145,24 +147,24 @@ Process_Information :: struct { } Startup_Info :: struct { - cb : u32, - reserved : ^u16, - desktop : ^u16, - title : ^u16, - x : u32, - y : u32, - x_size : u32, - y_size : u32, - x_count_chars : u32, - y_count_chars : u32, - fill_attribute : u32, - flags : u32, - show_window : u16, - _ : u16, - _ : ^byte, - stdin : Handle, - stdout : Handle, - stderr : Handle, + cb: u32, + reserved: Wstring, + desktop: Wstring, + title: Wstring, + x: u32, + y: u32, + x_size: u32, + y_size: u32, + x_count_chars: u32, + y_count_chars: u32, + fill_attribute: u32, + flags: u32, + show_window: u16, + _: u16, + _: cstring, + stdin: Handle, + stdout: Handle, + stderr: Handle, } Pixel_Format_Descriptor :: struct { @@ -276,16 +278,16 @@ Raw_Input :: struct { Overlapped :: struct { - internal : ^u64, - internal_high : ^u64, - using _ : struct #raw_union { - using _ : struct { - offset : u32, - offset_high : u32, + internal: ^u64, + internal_high: ^u64, + using _: struct #raw_union { + using _: struct { + offset: u32, + offset_high: u32, }, - pointer : rawptr, + pointer: rawptr, }, - event : Handle, + event: Handle, } File_Notify_Information :: struct { @@ -389,7 +391,7 @@ Hwnd_TOP :: Hwnd(uintptr(0)); BI_RGB :: 0; DIB_RGB_COLORS :: 0x00; -SRCCOPY: u32 : 0x00cc0020; +SRCCOPY: u32 : 0x00cc0020; MONITOR_DEFAULTTONULL :: 0x00000000; @@ -550,22 +552,22 @@ CP_UTF8 :: 65001; // UTF-8 translation @(default_calling_convention = "std") foreign kernel32 { @(link_name="GetLastError") get_last_error :: proc() -> i32 ---; - @(link_name="CreateProcessA") create_process_a :: proc(application_name, command_line: ^byte, + @(link_name="CreateProcessA") create_process_a :: proc(application_name, command_line: cstring, process_attributes, thread_attributes: ^Security_Attributes, inherit_handle: Bool, creation_flags: u32, environment: rawptr, - current_direcotry: ^byte, startup_info : ^Startup_Info, - process_information : ^Process_Information) -> Bool ---; + current_direcotry: cstring, startup_info: ^Startup_Info, + process_information: ^Process_Information) -> Bool ---; @(link_name="GetExitCodeProcess") get_exit_code_process :: proc(process: Handle, exit: ^u32) -> Bool ---; @(link_name="ExitProcess") exit_process :: proc(exit_code: u32) ---; - @(link_name="GetModuleHandleA") get_module_handle_a :: proc(module_name: ^byte) -> Hinstance ---; - @(link_name="GetModuleHandleW") get_module_handle_w :: proc(module_name: ^u16) -> Hinstance ---; + @(link_name="GetModuleHandleA") get_module_handle_a :: proc(module_name: cstring) -> Hinstance ---; + @(link_name="GetModuleHandleW") get_module_handle_w :: proc(module_name: Wstring) -> Hinstance ---; @(link_name="Sleep") sleep :: proc(ms: i32) -> i32 ---; @(link_name="QueryPerformanceFrequency") query_performance_frequency :: proc(result: ^i64) -> i32 ---; @(link_name="QueryPerformanceCounter") query_performance_counter :: proc(result: ^i64) -> i32 ---; - @(link_name="OutputDebugStringA") output_debug_string_a :: proc(c_str: ^byte) ---; + @(link_name="OutputDebugStringA") output_debug_string_a :: proc(c_str: cstring) ---; - @(link_name="GetCommandLineA") get_command_line_a :: proc() -> ^byte ---; - @(link_name="GetCommandLineW") get_command_line_w :: proc() -> ^u16 ---; + @(link_name="GetCommandLineA") get_command_line_a :: proc() -> cstring ---; + @(link_name="GetCommandLineW") get_command_line_w :: proc() -> Wstring ---; @(link_name="GetSystemMetrics") get_system_metrics :: proc(index: i32) -> i32 ---; @(link_name="GetCurrentThreadId") get_current_thread_id :: proc() -> u32 ---; @@ -578,12 +580,12 @@ foreign kernel32 { @(link_name="GetStdHandle") get_std_handle :: proc(h: i32) -> Handle ---; @(link_name="CreateFileA") - create_file_a :: proc(filename: ^byte, desired_access, share_module: u32, + create_file_a :: proc(filename: cstring, desired_access, share_module: u32, security: rawptr, creation, flags_and_attribs: u32, template_file: Handle) -> Handle ---; @(link_name="CreateFileW") - create_file_w :: proc(filename: ^u16, desired_access, share_module: u32, + create_file_w :: proc(filename: Wstring, desired_access, share_module: u32, security: rawptr, creation, flags_and_attribs: u32, template_file: Handle) -> Handle ---; @@ -592,34 +594,34 @@ foreign kernel32 { @(link_name="WriteFile") write_file :: proc(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool ---; @(link_name="GetFileSizeEx") get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool ---; - @(link_name="GetFileAttributesA") get_file_attributes_a :: proc(filename: ^byte) -> u32 ---; - @(link_name="GetFileAttributesW") get_file_attributes_w :: proc(filename: ^u16) -> u32 ---; - @(link_name="GetFileAttributesExA") get_file_attributes_ex_a :: proc(filename: ^byte, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool ---; + @(link_name="GetFileAttributesA") get_file_attributes_a :: proc(filename: cstring) -> u32 ---; + @(link_name="GetFileAttributesW") get_file_attributes_w :: proc(filename: Wstring) -> u32 ---; + @(link_name="GetFileAttributesExA") get_file_attributes_ex_a :: proc(filename: cstring, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: rawptr) -> Bool ---; @(link_name="GetFileInformationByHandle") get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool ---; - @(link_name="CreateDirectoryA") create_directory_a :: proc(path: ^byte, security_attributes: ^Security_Attributes) -> Bool ---; - @(link_name="CreateDirectoryW") create_directory_w :: proc(path: ^u16, security_attributes: ^Security_Attributes) -> Bool ---; + @(link_name="CreateDirectoryA") create_directory_a :: proc(path: cstring, security_attributes: ^Security_Attributes) -> Bool ---; + @(link_name="CreateDirectoryW") create_directory_w :: proc(path: Wstring, security_attributes: ^Security_Attributes) -> Bool ---; @(link_name="GetFileType") get_file_type :: proc(file_handle: Handle) -> u32 ---; @(link_name="SetFilePointer") set_file_pointer :: proc(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 ---; @(link_name="SetHandleInformation") set_handle_information :: proc(obj: Handle, mask, flags: u32) -> Bool ---; - @(link_name="FindFirstFileA") find_first_file_a :: proc(file_name : ^byte, data : ^Find_Data_A) -> Handle ---; - @(link_name="FindNextFileA") find_next_file_a :: proc(file : Handle, data : ^Find_Data_A) -> Bool ---; - - @(link_name="FindFirstFileW") find_first_file_w :: proc(file_name : ^u16, data : ^Find_Data_W) -> Handle ---; - @(link_name="FindNextFileW") find_next_file_w :: proc(file : Handle, data : ^Find_Data_W) -> Bool ---; - - @(link_name="FindClose") find_close :: proc(file : Handle) -> Bool ---; + @(link_name="FindFirstFileA") find_first_file_a :: proc(file_name: cstring, data: ^Find_Data_A) -> Handle ---; + @(link_name="FindNextFileA") find_next_file_a :: proc(file: Handle, data: ^Find_Data_A) -> Bool ---; - @(link_name="MoveFileExA") move_file_ex_a :: proc(existing, new: ^byte, flags: u32) -> Bool ---; - @(link_name="DeleteFileA") delete_file_a :: proc(file_name : ^byte) -> Bool ---; - @(link_name="CopyFileA") copy_file_a :: proc(existing, new: ^byte, fail_if_exists: Bool) -> Bool ---; + @(link_name="FindFirstFileW") find_first_file_w :: proc(file_name: Wstring, data: ^Find_Data_W) -> Handle ---; + @(link_name="FindNextFileW") find_next_file_w :: proc(file: Handle, data: ^Find_Data_W) -> Bool ---; - @(link_name="MoveFileExW") move_file_ex_w :: proc(existing, new: ^u16, flags: u32) -> Bool ---; - @(link_name="DeleteFileW") delete_file_w :: proc(file_name : ^u16) -> Bool ---; - @(link_name="CopyFileW") copy_file_w :: proc(existing, new: ^u16, fail_if_exists: Bool) -> Bool ---; + @(link_name="FindClose") find_close :: proc(file: Handle) -> Bool ---; + + @(link_name="MoveFileExA") move_file_ex_a :: proc(existing, new: cstring, flags: u32) -> Bool ---; + @(link_name="DeleteFileA") delete_file_a :: proc(file_name: cstring) -> Bool ---; + @(link_name="CopyFileA") copy_file_a :: proc(existing, new: cstring, fail_if_exists: Bool) -> Bool ---; + + @(link_name="MoveFileExW") move_file_ex_w :: proc(existing, new: Wstring, flags: u32) -> Bool ---; + @(link_name="DeleteFileW") delete_file_w :: proc(file_name: Wstring) -> Bool ---; + @(link_name="CopyFileW") copy_file_w :: proc(existing, new: Wstring, fail_if_exists: Bool) -> Bool ---; @(link_name="HeapAlloc") heap_alloc :: proc(h: Handle, flags: u32, bytes: int) -> rawptr ---; @(link_name="HeapReAlloc") heap_realloc :: proc(h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr ---; @@ -630,7 +632,7 @@ foreign kernel32 { @(link_name="LocalReAlloc") local_realloc :: proc(mem: rawptr, bytes: int, flags: uint) -> rawptr ---; @(link_name="LocalFree") local_free :: proc(mem: rawptr) -> rawptr ---; - @(link_name="FindFirstChangeNotificationA") find_first_change_notification_a :: proc(path: ^byte, watch_subtree: Bool, filter: u32) -> Handle ---; + @(link_name="FindFirstChangeNotificationA") find_first_change_notification_a :: proc(path: cstring, watch_subtree: Bool, filter: u32) -> Handle ---; @(link_name="FindNextChangeNotification") find_next_change_notification :: proc(h: Handle) -> Bool ---; @(link_name="FindCloseChangeNotification") find_close_change_notification :: proc(h: Handle) -> Bool ---; @@ -639,16 +641,16 @@ foreign kernel32 { bytes_returned: ^u32, overlapped: ^Overlapped, completion: rawptr) -> Bool ---; - @(link_name="WideCharToMultiByte") wide_char_to_multi_byte :: proc(code_page: u32, flags : u32, - wchar_str: ^u16, wchar: i32, - multi_str: ^byte, multi: i32, - default_char: ^byte, used_default_char: ^Bool) -> i32 ---; - - @(link_name="MultiByteToWideChar") multi_byte_to_wide_char :: proc(code_page: u32, flags : u32, - mb_str: ^byte, mb: i32, - wc_str : ^u16, wc: i32) -> i32 ---; - - @(link_name="CreateSemaphoreA") create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^byte) -> Handle ---; + @(link_name="WideCharToMultiByte") wide_char_to_multi_byte :: proc(code_page: u32, flags: u32, + wchar_str: Wstring, wchar: i32, + multi_str: cstring, multi: i32, + default_char: cstring, used_default_char: ^Bool) -> i32 ---; + + @(link_name="MultiByteToWideChar") multi_byte_to_wide_char :: proc(code_page: u32, flags: u32, + mb_str: cstring, mb: i32, + wc_str: Wstring, wc: i32) -> i32 ---; + + @(link_name="CreateSemaphoreA") create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: cstring) -> Handle ---; @(link_name="ReleaseSemaphore") release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool ---; @(link_name="WaitForSingleObject") wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 ---; } @@ -692,31 +694,31 @@ foreign kernel32 { @(link_name="EnterCriticalSection") enter_critical_section :: proc(critical_section: ^Critical_Section) ---; @(link_name="LeaveCriticalSection") leave_critical_section :: proc(critical_section: ^Critical_Section) ---; - @(link_name="CreateEventA") create_event_a :: proc(event_attributes: ^Security_Attributes, manual_reset, initial_state: Bool, name: ^byte) -> Handle ---; + @(link_name="CreateEventA") create_event_a :: proc(event_attributes: ^Security_Attributes, manual_reset, initial_state: Bool, name: cstring) -> Handle ---; - @(link_name="LoadLibraryA") load_library_a :: proc(c_str: ^byte) -> Hmodule ---; - @(link_name="LoadLibraryW") load_library_w :: proc(c_str: ^u16) -> Hmodule ---; + @(link_name="LoadLibraryA") load_library_a :: proc(c_str: cstring) -> Hmodule ---; + @(link_name="LoadLibraryW") load_library_w :: proc(c_str: Wstring) -> Hmodule ---; @(link_name="FreeLibrary") free_library :: proc(h: Hmodule) ---; - @(link_name="GetProcAddress") get_proc_address :: proc(h: Hmodule, c_str: ^byte) -> rawptr ---; + @(link_name="GetProcAddress") get_proc_address :: proc(h: Hmodule, c_str: cstring) -> rawptr ---; } @(default_calling_convention = "std") foreign user32 { @(link_name="GetDesktopWindow") get_desktop_window :: proc() -> Hwnd ---; - @(link_name="ShowCursor") show_cursor :: proc(show : Bool) ---; + @(link_name="ShowCursor") show_cursor :: proc(show: Bool) ---; @(link_name="GetCursorPos") get_cursor_pos :: proc(p: ^Point) -> Bool ---; @(link_name="SetCursorPos") set_cursor_pos :: proc(x, y: i32) -> Bool ---; @(link_name="ScreenToClient") screen_to_client :: proc(h: Hwnd, p: ^Point) -> Bool ---; @(link_name="ClientToScreen") client_to_screen :: proc(h: Hwnd, p: ^Point) -> Bool ---; @(link_name="PostQuitMessage") post_quit_message :: proc(exit_code: i32) ---; - @(link_name="SetWindowTextA") set_window_text_a :: proc(hwnd: Hwnd, c_string: ^byte) -> Bool ---; + @(link_name="SetWindowTextA") set_window_text_a :: proc(hwnd: Hwnd, c_string: cstring) -> Bool ---; @(link_name="RegisterClassExA") register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 ---; @(link_name="RegisterClassExW") register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 ---; @(link_name="CreateWindowExA") create_window_ex_a :: proc(ex_style: u32, - class_name, title: ^byte, + class_name, title: cstring, style: u32, x, y, w, h: i32, parent: Hwnd, menu: Hmenu, instance: Hinstance, @@ -724,7 +726,7 @@ foreign user32 { @(link_name="CreateWindowExW") create_window_ex_w :: proc(ex_style: u32, - class_name, title: ^u16, + class_name, title: Wstring, style: u32, x, y, w, h: i32, parent: Hwnd, menu: Hmenu, instance: Hinstance, @@ -735,14 +737,14 @@ foreign user32 { @(link_name="DispatchMessageA") dispatch_message_a :: proc(msg: ^Msg) -> Lresult ---; @(link_name="DispatchMessageW") dispatch_message_w :: proc(msg: ^Msg) -> Lresult ---; @(link_name="UpdateWindow") update_window :: proc(hwnd: Hwnd) -> Bool ---; - @(link_name="GetMessageA") get_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool ---; - @(link_name="GetMessageW") get_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max : u32) -> Bool ---; + @(link_name="GetMessageA") get_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max: u32) -> Bool ---; + @(link_name="GetMessageW") get_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max: u32) -> Bool ---; @(link_name="PeekMessageA") peek_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool ---; @(link_name="PeekMessageW") peek_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool ---; - @(link_name="PostMessageA") post_message :: proc(hwnd: Hwnd, msg, wparam, lparam : u32) -> Bool ---; + @(link_name="PostMessageA") post_message :: proc(hwnd: Hwnd, msg, wparam, lparam: u32) -> Bool ---; @(link_name="DefWindowProcA") def_window_proc_a :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult ---; @@ -753,7 +755,7 @@ foreign user32 { @(link_name="DescribePixelFormat") describe_pixel_format :: proc(dc: Hdc, pixel_format: i32, bytes: u32, pfd: ^Pixel_Format_Descriptor) -> i32 ---; @(link_name="GetMonitor_InfoA") get_monitor_info_a :: proc(monitor: Hmonitor, mi: ^Monitor_Info) -> Bool ---; - @(link_name="MonitorFromWindow") monitor_from_window :: proc(wnd: Hwnd, flags : u32) -> Hmonitor ---; + @(link_name="MonitorFromWindow") monitor_from_window :: proc(wnd: Hwnd, flags: u32) -> Hmonitor ---; @(link_name="SetWindowPos") set_window_pos :: proc(wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) ---; @@ -766,15 +768,15 @@ foreign user32 { @(link_name="GetWindowLongPtrW") get_window_long_ptr_w :: proc(wnd: Hwnd, index: i32) -> Long_Ptr ---; @(link_name="SetWindowLongPtrW") set_window_long_ptr_w :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr ---; - @(link_name="GetWindowText") get_window_text :: proc(wnd: Hwnd, str: ^byte, maxCount: i32) -> i32 ---; + @(link_name="GetWindowText") get_window_text :: proc(wnd: Hwnd, str: cstring, maxCount: i32) -> i32 ---; @(link_name="GetClientRect") get_client_rect :: proc(hwnd: Hwnd, rect: ^Rect) -> Bool ---; @(link_name="GetDC") get_dc :: proc(h: Hwnd) -> Hdc ---; @(link_name="ReleaseDC") release_dc :: proc(wnd: Hwnd, hdc: Hdc) -> i32 ---; - @(link_name="MapVirtualKeyA") map_virtual_key_a :: proc(scancode : u32, map_type : u32) -> u32 ---; - @(link_name="MapVirtualKeyW") map_virtual_key_w :: proc(scancode : u32, map_type : u32) -> u32 ---; + @(link_name="MapVirtualKeyA") map_virtual_key_a :: proc(scancode: u32, map_type: u32) -> u32 ---; + @(link_name="MapVirtualKeyW") map_virtual_key_w :: proc(scancode: u32, map_type: u32) -> u32 ---; @(link_name="GetKeyState") get_key_state :: proc(v_key: i32) -> i16 ---; @(link_name="GetAsyncKeyState") get_async_key_state :: proc(v_key: i32) -> i16 ---; @@ -782,9 +784,9 @@ foreign user32 { @(link_name="SetForegroundWindow") set_foreground_window :: proc(h: Hwnd) -> Bool ---; @(link_name="SetFocus") set_focus :: proc(h: Hwnd) -> Hwnd ---; - @(link_name="LoadCursorA") load_cursor_a :: proc(instance : Hinstance, cursor_name : ^u8) -> Hcursor ---; + @(link_name="LoadCursorA") load_cursor_a :: proc(instance: Hinstance, cursor_name: cstring) -> Hcursor ---; @(link_name="GetCursor") get_cursor :: proc() -> Hcursor ---; - @(link_name="SetCursor") set_cursor :: proc(cursor : Hcursor) -> Hcursor ---; + @(link_name="SetCursor") set_cursor :: proc(cursor: Hcursor) -> Hcursor ---; @(link_name="RegisterRawInputDevices") register_raw_input_devices :: proc(raw_input_device: ^Raw_Input_Device, num_devices, size: u32) -> Bool ---; @@ -814,7 +816,7 @@ foreign gdi32 { @(default_calling_convention = "std") foreign shell32 { - @(link_name="CommandLineToArgvW") command_line_to_argv_w :: proc(cmd_list: ^u16, num_args: ^i32) -> ^^u16 ---; + @(link_name="CommandLineToArgvW") command_line_to_argv_w :: proc(cmd_list: Wstring, num_args: ^i32) -> ^Wstring ---; } @(default_calling_convention = "std") diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 7ad75ac48..7d4c759d9 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1497,9 +1497,9 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) { err_type = y->type; } gbString type_string = type_to_string(err_type); + defer (gb_string_free(type_string)); err_str = gb_string_make(c->tmp_allocator, gb_bprintf("operator '%.*s' not defined for type '%s'", LIT(token_strings[op]), type_string)); - gb_string_free(type_string); } } else { gbString xt, yt; @@ -2279,6 +2279,8 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type) { case Basic_UntypedNil: if (is_type_any(target_type)) { target_type = t_untyped_nil; + } else if (is_type_cstring(target_type)) { + target_type = t_untyped_nil; } else if (!type_has_nil(target_type)) { operand->mode = Addressing_Invalid; convert_untyped_error(c, operand, target_type); diff --git a/src/types.cpp b/src/types.cpp index c0254729f..a5b6310f0 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1083,6 +1083,8 @@ bool type_has_nil(Type *t) { case Basic_rawptr: case Basic_any: return true; + case Basic_cstring: + return true; } return false; } break;