env.odin 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package os2
  2. import "base:runtime"
  3. import "core:strings"
  4. // `get_env` retrieves the value of the environment variable named by the key
  5. // It returns the value, which will be empty if the variable is not present
  6. // To distinguish between an empty value and an unset value, use lookup_env
  7. // NOTE: the value will be allocated with the supplied allocator
  8. @(require_results)
  9. get_env_alloc :: proc(key: string, allocator: runtime.Allocator) -> string {
  10. value, _ := lookup_env(key, allocator)
  11. return value
  12. }
  13. // `get_env` retrieves the value of the environment variable named by the key
  14. // It returns the value, which will be empty if the variable is not present
  15. // To distinguish between an empty value and an unset value, use lookup_env
  16. // NOTE: this version takes a backing buffer for the string value
  17. @(require_results)
  18. get_env_buf :: proc(buf: []u8, key: string) -> string {
  19. value, _ := lookup_env(buf, key)
  20. return value
  21. }
  22. get_env :: proc{get_env_alloc, get_env_buf}
  23. // `lookup_env` gets the value of the environment variable named by the key
  24. // If the variable is found in the environment the value (which can be empty) is returned and the boolean is true
  25. // Otherwise the returned value will be empty and the boolean will be false
  26. // NOTE: the value will be allocated with the supplied allocator
  27. @(require_results)
  28. lookup_env_alloc :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) {
  29. return _lookup_env_alloc(key, allocator)
  30. }
  31. // This version of `lookup_env` doesn't allocate and instead requires the user to provide a buffer.
  32. // Note that it is limited to environment names and values of 512 utf-16 values each
  33. // due to the necessary utf-8 <> utf-16 conversion.
  34. @(require_results)
  35. lookup_env_buf :: proc(buf: []u8, key: string) -> (value: string, err: Error) {
  36. return _lookup_env_buf(buf, key)
  37. }
  38. lookup_env :: proc{lookup_env_alloc, lookup_env_buf}
  39. // set_env sets the value of the environment variable named by the key
  40. // Returns Error on failure
  41. set_env :: proc(key, value: string) -> Error {
  42. return _set_env(key, value)
  43. }
  44. // unset_env unsets a single environment variable
  45. // Returns true on success, false on failure
  46. unset_env :: proc(key: string) -> bool {
  47. return _unset_env(key)
  48. }
  49. clear_env :: proc() {
  50. _clear_env()
  51. }
  52. // environ returns a copy of strings representing the environment, in the form "key=value"
  53. // NOTE: the slice of strings and the strings with be allocated using the supplied allocator
  54. @(require_results)
  55. environ :: proc(allocator: runtime.Allocator) -> ([]string, Error) {
  56. return _environ(allocator)
  57. }
  58. // Always allocates for consistency.
  59. replace_environment_placeholders :: proc(path: string, allocator: runtime.Allocator) -> (res: string) {
  60. path := path
  61. sb: strings.Builder
  62. strings.builder_init_none(&sb, allocator)
  63. for len(path) > 0 {
  64. switch path[0] {
  65. case '%': // Windows
  66. when ODIN_OS == .Windows {
  67. for r, i in path[1:] {
  68. if r == '%' {
  69. env_key := path[1:i+1]
  70. env_val := get_env(env_key, context.temp_allocator)
  71. strings.write_string(&sb, env_val)
  72. path = path[i+1:] // % is part of key, so skip 1 character extra
  73. }
  74. }
  75. } else {
  76. strings.write_rune(&sb, rune(path[0]))
  77. }
  78. case '$': // Posix
  79. when ODIN_OS != .Windows {
  80. env_key := ""
  81. dollar_loop: for r, i in path[1:] {
  82. switch r {
  83. case 'A'..='Z', 'a'..='z', '0'..='9', '_': // Part of key ident
  84. case:
  85. env_key = path[1:i+1]
  86. break dollar_loop
  87. }
  88. }
  89. if len(env_key) > 0 {
  90. env_val := get_env(env_key, context.temp_allocator)
  91. strings.write_string(&sb, env_val)
  92. path = path[len(env_key):]
  93. }
  94. } else {
  95. strings.write_rune(&sb, rune(path[0]))
  96. }
  97. case:
  98. strings.write_rune(&sb, rune(path[0]))
  99. }
  100. path = path[1:]
  101. }
  102. return strings.to_string(sb)
  103. }