From 630e4219fca3c42fd2d9b08677f11f3aaf61a5c7 Mon Sep 17 00:00:00 2001 From: Niklas Larsson Date: Tue, 16 Jun 2020 12:09:22 +0200 Subject: [PATCH 1/7] Fix unsetenv implement Windows support --- libs/base/System.idr | 4 ++-- support/c/idris_support.c | 16 ++++++++++++++++ support/c/windows/win_utils.c | 9 ++++++++- support/c/windows/win_utils.h | 1 + 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/libs/base/System.idr b/libs/base/System.idr index 261f7638a..66c259b10 100644 --- a/libs/base/System.idr +++ b/libs/base/System.idr @@ -36,9 +36,9 @@ getArgs = primIO prim__getArgs prim_getEnv : String -> PrimIO (Ptr String) %foreign support "idris2_getEnvPair" prim_getEnvPair : Int -> PrimIO (Ptr String) -%foreign libc "setenv" +%foreign support "idris2_setenv" prim_setEnv : String -> String -> Int -> PrimIO Int -%foreign libc "setenv" +%foreign support "idris2_unsetenv" prim_unsetEnv : String -> PrimIO Int export diff --git a/support/c/idris_support.c b/support/c/idris_support.c index 0585a74f1..8a75b4e27 100644 --- a/support/c/idris_support.c +++ b/support/c/idris_support.c @@ -73,3 +73,19 @@ int idris2_time() { char* idris2_getEnvPair(int i) { return *(environ + i); } + +int idris2_setenv(const char *name, const char *value, int overwrite) { +#ifdef _WIN32 + return win32_modenv(name, value); +#else + return setenv(name); +#endif +} + +int idris2_unsetenv(const char *name) { +#ifdef _WIN32 + return win32_modenv(name, ""); +#else + return unsetenv(name); +#endif +} \ No newline at end of file diff --git a/support/c/windows/win_utils.c b/support/c/windows/win_utils.c index b0042a478..8c4761c60 100644 --- a/support/c/windows/win_utils.c +++ b/support/c/windows/win_utils.c @@ -67,9 +67,16 @@ void win32_gettime(int64_t* sec, int64_t* nsec) *nsec = (t.QuadPart % 10000000)*100; *sec = t.QuadPart / 10000000; - *sec -= 11644473600; // LDAP epoch to Unix epoch + *sec -= 11644473600; // LDAP epoch to Unix epoch } void win32_sleep(int ms) { Sleep(ms); } + +int win32_modenv(const char* name, const char* value) { + char buffer[2000]; + if (strlen(name) + strlen(value) > 1998) return -1; + sprintf(buffer, "%s=%s", name, value); + return putenv(buffer); +} \ No newline at end of file diff --git a/support/c/windows/win_utils.h b/support/c/windows/win_utils.h index b9075e646..bd094dc4b 100644 --- a/support/c/windows/win_utils.h +++ b/support/c/windows/win_utils.h @@ -8,3 +8,4 @@ FILE *win32_u8fopen(const char *path, const char *mode); FILE *win32_u8popen(const char *path, const char *mode); void win32_gettime(int64_t* sec, int64_t* nsec); void win32_sleep(int ms); +int win32_modenv(const char* name, const char* value); From 6974b318a3afc1b0947680daa6015edc7e2a5951 Mon Sep 17 00:00:00 2001 From: Niklas Larsson Date: Tue, 16 Jun 2020 12:22:21 +0200 Subject: [PATCH 2/7] Add test for setenv and unsetenv --- support/c/idris_support.c | 2 +- tests/Main.idr | 2 +- tests/chez/chez024/Envy.idr | 16 ++++++++++++++++ tests/chez/chez024/expected | 6 ++++++ tests/chez/chez024/input | 2 ++ tests/chez/chez024/run | 3 +++ 6 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 tests/chez/chez024/Envy.idr create mode 100644 tests/chez/chez024/expected create mode 100644 tests/chez/chez024/input create mode 100644 tests/chez/chez024/run diff --git a/support/c/idris_support.c b/support/c/idris_support.c index 8a75b4e27..bb1470367 100644 --- a/support/c/idris_support.c +++ b/support/c/idris_support.c @@ -78,7 +78,7 @@ int idris2_setenv(const char *name, const char *value, int overwrite) { #ifdef _WIN32 return win32_modenv(name, value); #else - return setenv(name); + return setenv(name, value, overwrite); #endif } diff --git a/tests/Main.idr b/tests/Main.idr index 5a6d15b46..6bff484c0 100644 --- a/tests/Main.idr +++ b/tests/Main.idr @@ -113,7 +113,7 @@ chezTests = ["chez001", "chez002", "chez003", "chez004", "chez005", "chez006", "chez007", "chez008", "chez009", "chez010", "chez011", "chez012", "chez013", "chez014", "chez015", "chez016", "chez017", "chez018", - "chez019", "chez020", "chez021", "chez022", "chez023", + "chez019", "chez020", "chez021", "chez022", "chez023", "chez024", "reg001"] ideModeTests : List String diff --git a/tests/chez/chez024/Envy.idr b/tests/chez/chez024/Envy.idr new file mode 100644 index 000000000..ec391e420 --- /dev/null +++ b/tests/chez/chez024/Envy.idr @@ -0,0 +1,16 @@ +module Main + +import System + +main : IO () +main = do + ok <- setEnv "HELLO" "HI" True + printLn ok + Just str <- getEnv "HELLO" + | Nothing => pure () + putStrLn str + ok <- unsetEnv "HELLO" + printLn ok + Just str <- getEnv "HELLO" + | Nothing => putStrLn "Nothing there" + pure () diff --git a/tests/chez/chez024/expected b/tests/chez/chez024/expected new file mode 100644 index 000000000..cab317b46 --- /dev/null +++ b/tests/chez/chez024/expected @@ -0,0 +1,6 @@ +True +HI +True +Nothing there +1/1: Building Envy (Envy.idr) +Main> Main> Bye for now! diff --git a/tests/chez/chez024/input b/tests/chez/chez024/input new file mode 100644 index 000000000..fc5992c29 --- /dev/null +++ b/tests/chez/chez024/input @@ -0,0 +1,2 @@ +:exec main +:q diff --git a/tests/chez/chez024/run b/tests/chez/chez024/run new file mode 100644 index 000000000..5f8729e95 --- /dev/null +++ b/tests/chez/chez024/run @@ -0,0 +1,3 @@ +$1 --no-banner Envy.idr < input + +rm -rf build From 8633dde240c12c5abf918a4f2500e3033b848f81 Mon Sep 17 00:00:00 2001 From: Niklas Larsson Date: Tue, 16 Jun 2020 12:53:36 +0200 Subject: [PATCH 3/7] Add stdlib include --- support/c/idris_support.c | 1 + 1 file changed, 1 insertion(+) diff --git a/support/c/idris_support.c b/support/c/idris_support.c index bb1470367..3864b0737 100644 --- a/support/c/idris_support.c +++ b/support/c/idris_support.c @@ -5,6 +5,7 @@ #include #include #include +#include #ifdef _WIN32 extern char **_environ; From 854072820262b0fbe550c806de31ddf9c9a7063d Mon Sep 17 00:00:00 2001 From: Niklas Larsson Date: Tue, 16 Jun 2020 13:41:40 +0200 Subject: [PATCH 4/7] Handle overwrite on windows Expand test to test overwrite --- support/c/idris_support.c | 4 ++-- support/c/windows/win_utils.c | 3 ++- support/c/windows/win_utils.h | 2 +- tests/chez/chez024/Envy.idr | 6 +++++- tests/chez/chez024/expected | 2 ++ 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/support/c/idris_support.c b/support/c/idris_support.c index 3864b0737..1851b8549 100644 --- a/support/c/idris_support.c +++ b/support/c/idris_support.c @@ -77,7 +77,7 @@ char* idris2_getEnvPair(int i) { int idris2_setenv(const char *name, const char *value, int overwrite) { #ifdef _WIN32 - return win32_modenv(name, value); + return win32_modenv(name, value, overwrite); #else return setenv(name, value, overwrite); #endif @@ -85,7 +85,7 @@ int idris2_setenv(const char *name, const char *value, int overwrite) { int idris2_unsetenv(const char *name) { #ifdef _WIN32 - return win32_modenv(name, ""); + return win32_modenv(name, "", 1); #else return unsetenv(name); #endif diff --git a/support/c/windows/win_utils.c b/support/c/windows/win_utils.c index 8c4761c60..6d3e8d7e8 100644 --- a/support/c/windows/win_utils.c +++ b/support/c/windows/win_utils.c @@ -74,8 +74,9 @@ void win32_sleep(int ms) { Sleep(ms); } -int win32_modenv(const char* name, const char* value) { +int win32_modenv(const char* name, const char* value, int overwrite) { char buffer[2000]; + if (!overwrite && getenv(name)) return -1; if (strlen(name) + strlen(value) > 1998) return -1; sprintf(buffer, "%s=%s", name, value); return putenv(buffer); diff --git a/support/c/windows/win_utils.h b/support/c/windows/win_utils.h index bd094dc4b..30f1a19d6 100644 --- a/support/c/windows/win_utils.h +++ b/support/c/windows/win_utils.h @@ -8,4 +8,4 @@ FILE *win32_u8fopen(const char *path, const char *mode); FILE *win32_u8popen(const char *path, const char *mode); void win32_gettime(int64_t* sec, int64_t* nsec); void win32_sleep(int ms); -int win32_modenv(const char* name, const char* value); +int win32_modenv(const char* name, const char* value, int overwrite); diff --git a/tests/chez/chez024/Envy.idr b/tests/chez/chez024/Envy.idr index ec391e420..f8df09fc5 100644 --- a/tests/chez/chez024/Envy.idr +++ b/tests/chez/chez024/Envy.idr @@ -4,11 +4,15 @@ import System main : IO () main = do - ok <- setEnv "HELLO" "HI" True + ok <- setEnv "HELLO" "HI" False printLn ok Just str <- getEnv "HELLO" | Nothing => pure () putStrLn str + ok <- setEnv "HELLO" "HO" False + printLn ok + ok <- setEnv "HELLO" "EH" True + printLn ok ok <- unsetEnv "HELLO" printLn ok Just str <- getEnv "HELLO" diff --git a/tests/chez/chez024/expected b/tests/chez/chez024/expected index cab317b46..dff4264be 100644 --- a/tests/chez/chez024/expected +++ b/tests/chez/chez024/expected @@ -1,5 +1,7 @@ True HI +False +True True Nothing there 1/1: Building Envy (Envy.idr) From 24715a8fd089b04b0978117b785269f1e6c3018b Mon Sep 17 00:00:00 2001 From: Niklas Larsson Date: Tue, 16 Jun 2020 13:48:31 +0200 Subject: [PATCH 5/7] Overwrite should be true in the first call In case anybody has that defined in their environment. --- tests/chez/chez024/Envy.idr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/chez/chez024/Envy.idr b/tests/chez/chez024/Envy.idr index f8df09fc5..48744ce5a 100644 --- a/tests/chez/chez024/Envy.idr +++ b/tests/chez/chez024/Envy.idr @@ -4,7 +4,7 @@ import System main : IO () main = do - ok <- setEnv "HELLO" "HI" False + ok <- setEnv "HELLO" "HI" True printLn ok Just str <- getEnv "HELLO" | Nothing => pure () From 2e8f618f0005cf8ea76ec0cc3a281b889666d0ec Mon Sep 17 00:00:00 2001 From: Niklas Larsson Date: Tue, 16 Jun 2020 13:58:49 +0200 Subject: [PATCH 6/7] Apparently overwrite should report success --- support/c/windows/win_utils.c | 2 +- tests/chez/chez024/Envy.idr | 6 ++++++ tests/chez/chez024/expected | 4 +++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/support/c/windows/win_utils.c b/support/c/windows/win_utils.c index 6d3e8d7e8..5640bb804 100644 --- a/support/c/windows/win_utils.c +++ b/support/c/windows/win_utils.c @@ -76,7 +76,7 @@ void win32_sleep(int ms) { int win32_modenv(const char* name, const char* value, int overwrite) { char buffer[2000]; - if (!overwrite && getenv(name)) return -1; + if (!overwrite && getenv(name)) return 0; if (strlen(name) + strlen(value) > 1998) return -1; sprintf(buffer, "%s=%s", name, value); return putenv(buffer); diff --git a/tests/chez/chez024/Envy.idr b/tests/chez/chez024/Envy.idr index 48744ce5a..6617795a6 100644 --- a/tests/chez/chez024/Envy.idr +++ b/tests/chez/chez024/Envy.idr @@ -11,8 +11,14 @@ main = do putStrLn str ok <- setEnv "HELLO" "HO" False printLn ok + Just str <- getEnv "HELLO" + | Nothing => pure () + putStrLn str ok <- setEnv "HELLO" "EH" True printLn ok + Just str <- getEnv "HELLO" + | Nothing => pure () + putStrLn str ok <- unsetEnv "HELLO" printLn ok Just str <- getEnv "HELLO" diff --git a/tests/chez/chez024/expected b/tests/chez/chez024/expected index dff4264be..3f030c99d 100644 --- a/tests/chez/chez024/expected +++ b/tests/chez/chez024/expected @@ -1,7 +1,9 @@ True HI -False True +HI +True +EH True Nothing there 1/1: Building Envy (Envy.idr) From 0c7fc9b73c90dda8ee8f4c61bf842a540a14205d Mon Sep 17 00:00:00 2001 From: Niklas Larsson Date: Tue, 16 Jun 2020 14:09:12 +0200 Subject: [PATCH 7/7] simplify win32_modenv --- support/c/windows/win_utils.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/support/c/windows/win_utils.c b/support/c/windows/win_utils.c index 5640bb804..5fcb61a27 100644 --- a/support/c/windows/win_utils.c +++ b/support/c/windows/win_utils.c @@ -75,9 +75,6 @@ void win32_sleep(int ms) { } int win32_modenv(const char* name, const char* value, int overwrite) { - char buffer[2000]; if (!overwrite && getenv(name)) return 0; - if (strlen(name) + strlen(value) > 1998) return -1; - sprintf(buffer, "%s=%s", name, value); - return putenv(buffer); + return _putenv_s(name, value); } \ No newline at end of file