aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/os/environment.c.v
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/vlib/os/environment.c.v')
-rw-r--r--v_windows/v/vlib/os/environment.c.v108
1 files changed, 108 insertions, 0 deletions
diff --git a/v_windows/v/vlib/os/environment.c.v b/v_windows/v/vlib/os/environment.c.v
new file mode 100644
index 0000000..1b65a27
--- /dev/null
+++ b/v_windows/v/vlib/os/environment.c.v
@@ -0,0 +1,108 @@
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// Use of this source code is governed by an MIT license
+// that can be found in the LICENSE file.
+module os
+
+fn C.getenv(&char) &char
+
+// C.GetEnvironmentStringsW & C.FreeEnvironmentStringsW are defined only on windows
+fn C.GetEnvironmentStringsW() &u16
+
+fn C.FreeEnvironmentStringsW(&u16) int
+
+// `getenv` returns the value of the environment variable named by the key.
+pub fn getenv(key string) string {
+ unsafe {
+ $if windows {
+ s := C._wgetenv(key.to_wide())
+ if s == 0 {
+ return ''
+ }
+ return string_from_wide(s)
+ } $else {
+ s := C.getenv(&char(key.str))
+ if s == voidptr(0) {
+ return ''
+ }
+ // NB: C.getenv *requires* that the result be copied.
+ return cstring_to_vstring(s)
+ }
+ }
+}
+
+// os.setenv sets the value of an environment variable with `name` to `value`.
+pub fn setenv(name string, value string, overwrite bool) int {
+ $if windows {
+ format := '$name=$value'
+ if overwrite {
+ unsafe {
+ return C._putenv(&char(format.str))
+ }
+ } else {
+ if getenv(name).len == 0 {
+ unsafe {
+ return C._putenv(&char(format.str))
+ }
+ }
+ }
+ return -1
+ } $else {
+ unsafe {
+ return C.setenv(&char(name.str), &char(value.str), overwrite)
+ }
+ }
+}
+
+// os.unsetenv clears an environment variable with `name`.
+pub fn unsetenv(name string) int {
+ $if windows {
+ format := '$name='
+ return C._putenv(&char(format.str))
+ } $else {
+ return C.unsetenv(&char(name.str))
+ }
+}
+
+// See: https://linux.die.net/man/5/environ for unix platforms.
+// See: https://docs.microsoft.com/bg-bg/windows/win32/api/processenv/nf-processenv-getenvironmentstrings
+// os.environ returns a map of all the current environment variables
+
+fn unix_environ() &&char {
+ // TODO: remove this helper function, when `&&char(C.environ)` works properly
+ return voidptr(C.environ)
+}
+
+pub fn environ() map[string]string {
+ mut res := map[string]string{}
+ $if windows {
+ mut estrings := C.GetEnvironmentStringsW()
+ mut eline := ''
+ for c := estrings; *c != 0; {
+ eline = unsafe { string_from_wide(c) }
+ eq_index := eline.index_byte(`=`)
+ if eq_index > 0 {
+ res[eline[0..eq_index]] = eline[eq_index + 1..]
+ }
+ unsafe {
+ c = c + eline.len + 1
+ }
+ }
+ C.FreeEnvironmentStringsW(estrings)
+ } $else {
+ start := unix_environ()
+ mut i := 0
+ for {
+ x := unsafe { start[i] }
+ if x == 0 {
+ break
+ }
+ eline := unsafe { cstring_to_vstring(x) }
+ eq_index := eline.index_byte(`=`)
+ if eq_index > 0 {
+ res[eline[0..eq_index]] = eline[eq_index + 1..]
+ }
+ i++
+ }
+ }
+ return res
+}