diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2025-06-08 14:56:41 +0200 |
|---|---|---|
| committer | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2025-06-08 14:56:41 +0200 |
| commit | 77f4199af6bd332f58f342c6f536a2cff9d26397 (patch) | |
| tree | 03913e4363c20f91cf117f655023a103a5abbef5 | |
| parent | 00b67831d11b2b0f4db904af9c58be4a2cd4470c (diff) | |
Simplify `_xdg_user_dirs_lookup`
| -rw-r--r-- | core/os/os2/errors.odin | 32 | ||||
| -rw-r--r-- | core/os/os2/user_posix.odin | 70 |
2 files changed, 41 insertions, 61 deletions
diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin index 0aff335bb..a73aee9a6 100644 --- a/core/os/os2/errors.odin +++ b/core/os/os2/errors.odin @@ -28,6 +28,7 @@ General_Error :: enum u32 { Pattern_Has_Separator, No_HOME_Variable, + Wordexp_Failed, Unsupported, } @@ -61,21 +62,22 @@ error_string :: proc(ferr: Error) -> string { case General_Error: switch e { case .None: return "" - case .Permission_Denied: return "permission denied" - case .Exist: return "file already exists" - case .Not_Exist: return "file does not exist" - case .Closed: return "file already closed" - case .Timeout: return "i/o timeout" - case .Broken_Pipe: return "Broken pipe" - case .No_Size: return "file has no definite size" - case .Invalid_File: return "invalid file" - case .Invalid_Dir: return "invalid directory" - case .Invalid_Path: return "invalid path" - case .Invalid_Callback: return "invalid callback" - case .Invalid_Command: return "invalid command" - case .Unsupported: return "unsupported" - case .Pattern_Has_Separator: return "pattern has separator" - case .No_HOME_Variable: return "no $HOME variable" + case .Permission_Denied: return "permission denied" + case .Exist: return "file already exists" + case .Not_Exist: return "file does not exist" + case .Closed: return "file already closed" + case .Timeout: return "i/o timeout" + case .Broken_Pipe: return "Broken pipe" + case .No_Size: return "file has no definite size" + case .Invalid_File: return "invalid file" + case .Invalid_Dir: return "invalid directory" + case .Invalid_Path: return "invalid path" + case .Invalid_Callback: return "invalid callback" + case .Invalid_Command: return "invalid command" + case .Unsupported: return "unsupported" + case .Pattern_Has_Separator: return "pattern has separator" + case .No_HOME_Variable: return "no $HOME variable" + case .Wordexp_Failed: return "posix.wordexp was unable to expand" } case io.Error: switch e { diff --git a/core/os/os2/user_posix.odin b/core/os/os2/user_posix.odin index 2c31f7eb8..f271b8913 100644 --- a/core/os/os2/user_posix.odin +++ b/core/os/os2/user_posix.odin @@ -2,6 +2,7 @@ package os2 import "base:runtime" +import "core:encoding/ini" import "core:strings" import "core:sys/posix" @@ -153,53 +154,30 @@ _xdg_lookup :: proc(xdg_key: string, fallback_suffix: string, allocator: runtime // If `<config-dir>/user-dirs.dirs` doesn't exist, or `xdg_key` can't be found there: returns `""` _xdg_user_dirs_lookup :: proc(xdg_key: string, allocator: runtime.Allocator) -> (dir: string, err: Error) { temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator }) + config_dir := user_config_dir(temp_allocator) or_return + user_dirs_path := concatenate({config_dir, "/user-dirs.dirs"}, temp_allocator) or_return + content := read_entire_file(user_dirs_path, temp_allocator) or_return + + it := ini.Iterator{ + section = "", + _src = string(content), + options = ini.Options{ + comment = "#", + key_lower_case = false, + }, + } + + for k, v in ini.iterate(&it) { + if k == xdg_key { + we: posix.wordexp_t + defer posix.wordfree(&we) + + if _err := posix.wordexp(strings.clone_to_cstring(v, temp_allocator), &we, nil); _err != nil || we.we_wordc != 1 { + return "", .Wordexp_Failed + } - config_dir := user_config_dir(temp_allocator) or_return - - user_dirs_path := concatenate({config_dir, "/user-dirs.dirs"}, temp_allocator) or_return - user_dirs_content_bytes, read_err := read_entire_file(user_dirs_path, temp_allocator) - if read_err == .Not_Exist { - return - } else if read_err != nil { - err = read_err - return - } - user_dirs_content := string(user_dirs_content_bytes) - - lines := strings.split_lines(user_dirs_content, temp_allocator) or_return - - home_env := get_env("HOME", temp_allocator) - if home_env == "" { - err = .No_HOME_Variable - return - } - - for line in lines { - ss := strings.split_n(line, "=", 2, temp_allocator) or_return - (len(ss) == 2) or_continue - sl := strings.trim_space(ss[0]) - sr := ss[1] - - (sl == xdg_key) or_continue - - (len(sr) > 2) or_continue - - lq := strings.index_byte(sr, '"') - (lq != -1) or_continue - rq := strings.index_byte(sr[lq+1:], '"') + lq+1 - (rq != -1) or_continue - - sr = sr[lq+1:rq] - - we: posix.wordexp_t - we_err := posix.wordexp(strings.clone_to_cstring(sr, temp_allocator), &we, nil) - (we_err == nil) or_continue - defer posix.wordfree(&we) - - (we.we_wordc == 1) or_continue - - dir = strings.clone_from_cstring(we.we_wordv[0], allocator) or_return - return + return strings.clone_from_cstring(we.we_wordv[0], allocator) + } } return }
\ No newline at end of file |