on master help sign in
Merge pull request #491 from gabemc/feature/environment

Adding several functions to interact with environment variables.

commitf86ba912054a11cfbeeefb15a4adb4e5be4be364 authorEdwin Brady <edwin.brady@gmail.com> dateSun 22 Sep 2013, 06:03 (13 years ago) parent93ae4985e8a597
5 files changed+53−10
lib/Prelude.idr+1−1 lib/System.idr+39−2 llvm/defs.c+5−2 rts/idris_stdfgn.c+6−4 rts/idris_stdfgn.h+2−1
lib/Prelude.idr+1−1
@@ -480,7 +480,7 @@ nullPtr p = do ok <- mkForeign (FFun "isNull" [FPtr] FInt) p
480480
481481partial
482482nullStr : String -> IO Bool
483−nullStr p = do ok <- mkForeign (FFun "isNullString" [FString] FInt) p
483+nullStr p = do ok <- mkForeign (FFun "isNull" [FString] FInt) p
484484 return (ok /= 0);
485485
486486partial
lib/System.idr+39−2
@@ -20,17 +20,54 @@ getArgs = do n <- numArgs
2020 do arg <- getArg i
2121 ga' (arg :: acc) (i+1) n
2222
23+-- Retrieves an value from the environment, if the given key is present,
24+-- otherwise it returns Nothing.
2325getEnv : String -> IO (Maybe String)
2426getEnv key = do
2527 str_ptr <- getEnv'
26− exists <- nullStr str_ptr
27− if exists
28+ is_nil <- nullStr str_ptr
29+ if is_nil
2830 then pure Nothing
2931 else pure (Just str_ptr)
3032 where
3133 getEnv' : IO String
3234 getEnv' = mkForeign (FFun "getenv" [FString] FString) key
3335
36+-- Sets an environment variable with a given value.
37+-- Returns true if the operation was successful.
38+setEnv : String -> String -> IO Bool
39+setEnv key value = do
40+ ok <- mkForeign (FFun "setenv" [FString, FString, FInt] FInt) key value 1
41+ return (ok == 0)
42+
43+-- Unsets an environment variable.
44+-- Returns true if the variable was able to be unset.
45+unsetEnv : String -> IO Bool
46+unsetEnv key = do
47+ ok <- mkForeign (FFun "unsetenv" [FString] FInt) key
48+ return (ok == 0)
49+
50+getEnvironment : IO (List (String, String))
51+getEnvironment = getAllPairs 0 []
52+ where
53+ getEnvPair : Int -> IO String
54+ getEnvPair i = mkForeign (FFun "getEnvPair" [FInt] FString) i
55+
56+ splitEq : String -> (String, String)
57+ splitEq str =
58+ -- FIXME: There has to be a better way to split this up
59+ let (k, v) = break (== '=') str in
60+ let (_, v') = break (/= '=') v in
61+ (k, v')
62+
63+ getAllPairs : Int -> List String -> IO (List (String, String))
64+ getAllPairs n acc = do
65+ envPair <- getEnvPair n
66+ is_nil <- nullStr envPair
67+ if is_nil
68+ then return $ reverse $ map splitEq acc
69+ else getAllPairs (n + 1) (envPair :: acc)
70+
3471exit : Int -> IO ()
3572exit code = mkForeign (FFun "exit" [FInt] FUnit) code
3673
llvm/defs.c+5−2
@@ -1,9 +1,12 @@
1+#include <stdlib.h>
12#include <stdio.h>
23#include <gmp.h>
34#include <gc.h>
45#include <string.h>
56#include <inttypes.h>
67
8+extern char** environ;
9+
710void putStr(const char *str) {
811 fputs(str, stdout);
912}
@@ -119,8 +122,8 @@ int isNull(void* ptr) {
119122 return ptr==NULL;
120123}
121124
122−int isNullString(char* str) {
123− return str==NULL;
125+char* getEnvPair(int i) {
126+ return *(environ + i);
124127}
125128
126129void idris_memset(void* ptr, size_t offset, uint8_t c, size_t size) {
rts/idris_stdfgn.c+6−4
@@ -1,6 +1,8 @@
11#include "idris_stdfgn.h"
22#include "idris_rts.h"
33
4+extern char** environ;
5+
46void putStr(char* str) {
57 printf("%s", str);
68}
@@ -34,10 +36,10 @@ int isNull(void* ptr) {
3436 return ptr==NULL;
3537}
3638
37−int isNullString(char* str) {
38− return str==NULL;
39−}
40−
4139void* idris_stdin() {
4240 return (void*)stdin;
4341}
42+
43+char* getEnvPair(int i) {
44+ return *(environ + i);
45+}
rts/idris_stdfgn.h+2−1
@@ -13,7 +13,8 @@ int fileError(void* h);
1313void fputStr(void*h, char* str);
1414
1515int isNull(void* ptr);
16−int isNullString(char* str);
1716void* idris_stdin();
1817
18+char* getEnvPair(int i);
19+
1920#endif