diff options
| author | Daniel Gavin <danielgavin5@hotmail.com> | 2022-05-13 22:05:52 +0200 |
|---|---|---|
| committer | Daniel Gavin <danielgavin5@hotmail.com> | 2022-05-13 22:05:52 +0200 |
| commit | cac294ccb3baf33aa91a7dbcbc17b538c92a23c7 (patch) | |
| tree | 547742baf50695523115b195fd8a789de6da4053 | |
| parent | ae7ebdd43685f74e6c1077655f4d69ae6f2d9fe4 (diff) | |
correcting cases for windows to not have to lowercase all the time.
| -rw-r--r-- | src/common/uri.odin | 15 | ||||
| -rw-r--r-- | src/common/util_windows.odin | 54 | ||||
| -rw-r--r-- | src/server/documents.odin | 6 | ||||
| -rw-r--r-- | src/server/requests.odin | 7 |
4 files changed, 68 insertions, 14 deletions
diff --git a/src/common/uri.odin b/src/common/uri.odin index a9cdc14..b8f562b 100644 --- a/src/common/uri.odin +++ b/src/common/uri.odin @@ -16,7 +16,6 @@ Uri :: struct { //Note(Daniel, This is an extremely incomplete uri parser and for now ignores fragment and query and only handles file schema) parse_uri :: proc(value: string, allocator: mem.Allocator) -> (Uri, bool) { - uri: Uri decoded, ok := decode_percent(value, allocator) @@ -62,15 +61,14 @@ create_uri :: proc(path: string, allocator: mem.Allocator) -> Uri { uri: Uri - uri.uri = strings.to_string(builder) + uri.uri = strings.to_string(builder) uri.decode_full = strings.clone(path_forward, allocator) - uri.path = uri.decode_full + uri.path = uri.decode_full return uri } delete_uri :: proc(uri: Uri) { - if uri.uri != "" { delete(uri.uri) } @@ -81,18 +79,15 @@ delete_uri :: proc(uri: Uri) { } encode_percent :: proc(value: string, allocator: mem.Allocator) -> string { - builder := strings.make_builder(allocator) data := transmute([]u8)value index: int for index < len(value) { - r, w := utf8.decode_rune(data[index:]) if r > 127 || r == ':' { - for i := 0; i < w; i += 1 { strings.write_string(&builder, strings.concatenate({"%", fmt.tprintf("%X", data[index + i])}, context.temp_allocator)) @@ -109,13 +104,11 @@ encode_percent :: proc(value: string, allocator: mem.Allocator) -> string { @(private) starts_with :: proc(value: string, starts_with: string) -> bool { - if len(value) < len(starts_with) { return false } for i := 0; i < len(starts_with); i += 1 { - if value[i] != starts_with[i] { return false } @@ -126,15 +119,11 @@ starts_with :: proc(value: string, starts_with: string) -> bool { @(private) decode_percent :: proc(value: string, allocator: mem.Allocator) -> (string, bool) { - builder := strings.make_builder(allocator) for i := 0; i < len(value); i += 1 { - if value[i] == '%' { - if i + 2 < len(value) { - v, ok := strconv.parse_i64_of_base(value[i + 1:i + 3], 16) if !ok { diff --git a/src/common/util_windows.odin b/src/common/util_windows.odin index bf89c47..d08d593 100644 --- a/src/common/util_windows.odin +++ b/src/common/util_windows.odin @@ -7,13 +7,65 @@ import "core:log" import "core:sys/win32" +FORMAT_MESSAGE_FROM_SYSTEM :: 0x00001000 +FORMAT_MESSAGE_IGNORE_INSERTS :: 0x00000200 + + foreign import kernel32 "system:kernel32.lib" @(default_calling_convention = "std") foreign kernel32 { - @(link_name = "CreatePipe")create_pipe :: proc (hReadPipe, hWritePipe: ^win32.Handle, lpPipeAttributes: ^win32.Security_Attributes, nSize: i32) -> i32 --- + @(link_name = "CreatePipe") create_pipe :: proc(hReadPipe, hWritePipe: ^win32.Handle, lpPipeAttributes: ^win32.Security_Attributes, nSize: i32) -> i32 --- + @(link_name = "GetFinalPathNameByHandleA") get_final_pathname_by_handle_a :: proc(handle: win32.Handle, lpszFilePath: cstring, cchFilePath: u32, dwFlags: u32) -> u32 --- + @(link_name = "FormatMessageA") + format_message_a :: proc( + flags: i32, + source: rawptr, + message_id: i32, + langauge_id: i32, + buffer: cstring, + size: i32, + va: rawptr, + ) -> i32 --- +} + +get_case_sensitive_path :: proc(path: string, allocator := context.temp_allocator) -> string { + file := win32.create_file_a(strings.clone_to_cstring(path, context.temp_allocator), 0, win32.FILE_SHARE_READ, nil, win32.OPEN_EXISTING, win32.FILE_FLAG_BACKUP_SEMANTICS, nil) + + if(file == win32.INVALID_HANDLE) + { + log_last_error() + return ""; + } + + buffer := make([]u8, 512, context.temp_allocator) + + ret := get_final_pathname_by_handle_a(file, cast(cstring)&buffer[0], cast(u32)len(buffer), 0) + + return strings.clone_from_cstring(cast(cstring)&buffer[4], allocator) } +log_last_error :: proc() { + err_text: [512]byte + + err := win32.get_last_error() + + error_string := cstring(&err_text[0]) + + if (format_message_a( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nil, + err, + (1 << 10) | 0, + error_string, + len(err_text) - 1, + nil, + ) != 0) { + log.error(error_string) + } +} + + run_executable :: proc(command: string, stdout: ^[]byte) -> (u32, bool, []byte) { stdout_read: win32.Handle diff --git a/src/server/documents.odin b/src/server/documents.odin index a360bd3..b702e0c 100644 --- a/src/server/documents.odin +++ b/src/server/documents.odin @@ -7,6 +7,7 @@ import "core:os" import "core:odin/parser" import "core:odin/ast" import "core:odin/tokenizer" +import "core:path/filepath" import path "core:path/slashpath" import "core:mem" @@ -352,6 +353,11 @@ parse_imports :: proc(document: ^common.Document, config: ^common.Config) { document.package_name = path.dir(document.uri.path) + when ODIN_OS == .Windows { + forward, _ := filepath.to_slash(common.get_case_sensitive_path(document.package_name), context.temp_allocator) + document.package_name = strings.clone(forward) + } + for imp, index in document.ast.imports { if i := strings.index(imp.fullpath, "\""); i == -1 { continue diff --git a/src/server/requests.odin b/src/server/requests.odin index c7b5c95..b30b18c 100644 --- a/src/server/requests.odin +++ b/src/server/requests.odin @@ -462,6 +462,13 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C config.collections["vendor"] = path.join(elems = {forward_path, "vendor"}, allocator = context.allocator) } + when ODIN_OS == .Windows { + for k, v in config.collections { + forward, _ := filepath.to_slash(common.get_case_sensitive_path(v), context.temp_allocator) + config.collections[k] = strings.clone(forward, context.allocator) + } + } + for format in initialize_params.capabilities.textDocument.hover.contentFormat { if format == "markdown" { config.hover_support_md = true |