aboutsummaryrefslogtreecommitdiff
path: root/core/os
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2025-06-08 14:56:41 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2025-06-08 14:56:41 +0200
commit77f4199af6bd332f58f342c6f536a2cff9d26397 (patch)
tree03913e4363c20f91cf117f655023a103a5abbef5 /core/os
parent00b67831d11b2b0f4db904af9c58be4a2cd4470c (diff)
Simplify `_xdg_user_dirs_lookup`
Diffstat (limited to 'core/os')
-rw-r--r--core/os/os2/errors.odin32
-rw-r--r--core/os/os2/user_posix.odin70
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