user_posix.odin 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #+build !windows
  2. package os2
  3. import "base:runtime"
  4. import "core:encoding/ini"
  5. import "core:strings"
  6. _user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  7. #partial switch ODIN_OS {
  8. case .Darwin:
  9. return _xdg_lookup("", "/Library/Caches", allocator)
  10. case: // Unix
  11. return _xdg_lookup("XDG_CACHE_HOME", "/.cache", allocator)
  12. }
  13. }
  14. _user_config_dir :: proc(allocator: runtime.Allocator, _roaming: bool) -> (dir: string, err: Error) {
  15. #partial switch ODIN_OS {
  16. case .Darwin:
  17. return _xdg_lookup("", "/Library/Application Support", allocator)
  18. case: // Unix
  19. return _xdg_lookup("XDG_CONFIG_HOME", "/.config", allocator)
  20. }
  21. }
  22. _user_state_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  23. #partial switch ODIN_OS {
  24. case .Darwin:
  25. return _xdg_lookup("", "/Library/Application Support", allocator)
  26. case: // Unix
  27. return _xdg_lookup("XDG_STATE_HOME", "/.local/state", allocator)
  28. }
  29. }
  30. _user_log_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  31. #partial switch ODIN_OS {
  32. case .Darwin:
  33. return _xdg_lookup("", "/Library/Logs", allocator)
  34. case: // Unix
  35. return _xdg_lookup("XDG_STATE_HOME", "/.local/state", allocator)
  36. }
  37. }
  38. _user_data_dir :: proc(allocator: runtime.Allocator, _roaming: bool) -> (dir: string, err: Error) {
  39. #partial switch ODIN_OS {
  40. case .Darwin:
  41. return _xdg_lookup("", "/Library/Application Support", allocator)
  42. case: // Unix
  43. return _xdg_lookup("XDG_DATA_HOME", "/.local/share", allocator)
  44. }
  45. }
  46. _user_music_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  47. #partial switch ODIN_OS {
  48. case .Darwin:
  49. return _xdg_lookup("", "/Music", allocator)
  50. case: // Unix
  51. return _xdg_lookup("XDG_MUSIC_DIR", "/Music", allocator)
  52. }
  53. }
  54. _user_desktop_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  55. #partial switch ODIN_OS {
  56. case .Darwin:
  57. return _xdg_lookup("", "/Desktop", allocator)
  58. case: // Unix
  59. return _xdg_lookup("XDG_DESKTOP_DIR", "/Desktop", allocator)
  60. }
  61. }
  62. _user_documents_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  63. #partial switch ODIN_OS {
  64. case .Darwin:
  65. return _xdg_lookup("", "/Documents", allocator)
  66. case: // Unix
  67. return _xdg_lookup("XDG_DOCUMENTS_DIR", "/Documents", allocator)
  68. }
  69. }
  70. _user_downloads_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  71. #partial switch ODIN_OS {
  72. case .Darwin:
  73. return _xdg_lookup("", "/Downloads", allocator)
  74. case: // Unix
  75. return _xdg_lookup("XDG_DOWNLOAD_DIR", "/Downloads", allocator)
  76. }
  77. }
  78. _user_pictures_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  79. #partial switch ODIN_OS {
  80. case .Darwin:
  81. return _xdg_lookup("", "/Pictures", allocator)
  82. case: // Unix
  83. return _xdg_lookup("XDG_PICTURES_DIR", "/Pictures", allocator)
  84. }
  85. }
  86. _user_public_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  87. #partial switch ODIN_OS {
  88. case .Darwin:
  89. return _xdg_lookup("", "/Public", allocator)
  90. case: // Unix
  91. return _xdg_lookup("XDG_PUBLICSHARE_DIR", "/Public", allocator)
  92. }
  93. }
  94. _user_videos_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  95. #partial switch ODIN_OS {
  96. case .Darwin:
  97. return _xdg_lookup("", "/Movies", allocator)
  98. case: // Unix
  99. return _xdg_lookup("XDG_VIDEOS_DIR", "/Videos", allocator)
  100. }
  101. }
  102. _user_home_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) {
  103. if v := get_env("HOME", allocator); v != "" {
  104. return v, nil
  105. }
  106. err = .No_HOME_Variable
  107. return
  108. }
  109. _xdg_lookup :: proc(xdg_key: string, fallback_suffix: string, allocator: runtime.Allocator) -> (dir: string, err: Error) {
  110. temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
  111. if xdg_key == "" { // Darwin doesn't have XDG paths.
  112. dir = get_env("HOME", temp_allocator)
  113. if dir == "" {
  114. err = .No_HOME_Variable
  115. return
  116. }
  117. return concatenate({dir, fallback_suffix}, allocator)
  118. } else {
  119. if strings.ends_with(xdg_key, "_DIR") {
  120. dir = _xdg_user_dirs_lookup(xdg_key, allocator) or_return
  121. } else {
  122. dir = get_env(xdg_key, allocator)
  123. }
  124. if dir == "" {
  125. dir = get_env("HOME", temp_allocator)
  126. if dir == "" {
  127. err = .No_HOME_Variable
  128. return
  129. }
  130. dir = concatenate({dir, fallback_suffix}, allocator) or_return
  131. }
  132. return
  133. }
  134. }
  135. // If `<config-dir>/user-dirs.dirs` doesn't exist, or `xdg_key` can't be found there: returns `""`
  136. _xdg_user_dirs_lookup :: proc(xdg_key: string, allocator: runtime.Allocator) -> (dir: string, err: Error) {
  137. temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator })
  138. config_dir := user_config_dir(temp_allocator) or_return
  139. user_dirs_path := concatenate({config_dir, "/user-dirs.dirs"}, temp_allocator) or_return
  140. content := read_entire_file(user_dirs_path, temp_allocator) or_return
  141. it := ini.Iterator{
  142. section = "",
  143. _src = string(content),
  144. options = ini.Options{
  145. comment = "#",
  146. key_lower_case = false,
  147. },
  148. }
  149. for k, v in ini.iterate(&it) {
  150. if k == xdg_key {
  151. return replace_environment_placeholders(v, allocator), nil
  152. }
  153. }
  154. return
  155. }