diff --git a/Makefile b/Makefile index cb78dda..accd677 100644 --- a/Makefile +++ b/Makefile @@ -76,6 +76,7 @@ TESTDIR := $(SRC)/tests SRCS := $(SRC)/src/tomlua.c \ $(SRC)/src/decode.c \ $(SRC)/src/encode.c \ + $(SRC)/src/env.c \ $(SRC)/src/dates.c CLI_SRCS := $(SRC)/src/tomlua_cli.c \ diff --git a/src/env.c b/src/env.c new file mode 100644 index 0000000..6be66ab --- /dev/null +++ b/src/env.c @@ -0,0 +1,54 @@ +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +static int env__newindex(lua_State *L) { + const char *key = luaL_checkstring(L, 2); +#ifdef _WIN32 + if (lua_isnil(L, 3)) { + if (SetEnvironmentVariable(key, NULL) == 0) { + return luaL_error(L, "failed to unset env var"); + } + } else if (lua_type(L, 3) == LUA_TSTRING) { + if (SetEnvironmentVariable(key, lua_tostring(L, 3)) == 0) { + return luaL_error(L, "failed to set env var"); + } +#else + if (lua_isnil(L, 3)) { + if (unsetenv(key) != 0) { + return luaL_error(L, "failed to unset env var"); + } + } else if (lua_type(L, 3) == LUA_TSTRING) { + if (setenv(key, lua_tostring(L, 3), 1) != 0) { + return luaL_error(L, "failed to set env var"); + } +#endif + } else { + return luaL_error(L, "env values must be strings or nil"); + } + return 0; +} + +static int env__index(lua_State *L) { + const char *key = luaL_checkstring(L, 2); + const char *val = getenv(key); + if (val) + lua_pushstring(L, val); + else + lua_pushnil(L); + return 1; +} + +int luaopen_tomlua_env(lua_State *L) { + lua_newtable(L); // module table + lua_newtable(L); // metatable + lua_pushcfunction(L, env__index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, env__newindex); + lua_setfield(L, -2, "__newindex"); + lua_setmetatable(L, -2); // setmetatable(t, mt) + return 1; // return env table +} diff --git a/src/tomlua_cli.c b/src/tomlua_cli.c index 724c6e9..41a7fd4 100644 --- a/src/tomlua_cli.c +++ b/src/tomlua_cli.c @@ -8,6 +8,7 @@ #include extern int luaopen_tomlua(lua_State *L); +extern int luaopen_tomlua_env(lua_State *L); static void inject_tomlua(lua_State *L) { lua_getglobal(L, "package"); @@ -16,6 +17,9 @@ static void inject_tomlua(lua_State *L) { lua_pushcfunction(L, luaopen_tomlua); lua_setfield(L, -2, "tomlua"); + lua_pushcfunction(L, luaopen_tomlua_env); + lua_setfield(L, -2, "tomlua.env"); + lua_pop(L, 2); } diff --git a/tests/opts_test.lua b/tests/opts_test.lua index b23d4e1..797c4a4 100644 --- a/tests/opts_test.lua +++ b/tests/opts_test.lua @@ -42,3 +42,12 @@ define("opts({ int_keys = true }) doesn't copy", function() local opts = tomlua.opts() ok(type(opts) == "table", "opts when called with no args should return a table") end) + +define("require('tomlua.env') tests", function() + local env = require("tomlua.env") + ok(env ~= nil, "tomlua.env should be available") + env.TESTVARIABLE = "HELLO" + ok(env.TESTVARIABLE == os.getenv("TESTVARIABLE"), "tomlua.env should get the env var") + env.TESTVARIABLE = nil + ok(env.TESTVARIABLE == os.getenv("TESTVARIABLE"), "tomlua.env should be removed just like the env var") +end)