Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions src/opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static inline TomluaUserOpts *toml_user_opts_copy(TomluaUserOpts dst, TomluaUser
}

// negative taridx means all false
static bool opts_parse(lua_State *L, TomluaUserOpts dst, int taridx, int optidx) {
static bool opts_parse(lua_State *L, TomluaUserOpts dst, int taridx) {
if (taridx > 0) {
luaL_checktype(L, taridx, LUA_TTABLE);
for (int i = 0; i < TOMLOPTS_LENGTH; i++) {
Expand All @@ -50,15 +50,19 @@ static bool opts_parse(lua_State *L, TomluaUserOpts dst, int taridx, int optidx)
} else {
memset(dst, false, sizeof(TomluaUserOpts));
}
for (int i = 0; i < TOMLOPTS_LENGTH; i++) {
lua_pushboolean(L, dst[i]);
lua_setfield(L, optidx, toml_opts_names[i]);
}
return false;
}
static int opts_call(lua_State *L) {
TomluaUserOpts *opts = (TomluaUserOpts *)lua_touserdata(L, lua_upvalueindex(1));
opts_parse(L, *opts, 2, 1);
if (lua_gettop(L) == 1) {
lua_newtable(L);
for (int i = 0; i < TOMLOPTS_LENGTH; i++) {
lua_pushboolean(L, (*opts)[i]);
lua_setfield(L, -2, toml_opts_names[i]);
}
return 1;
}
opts_parse(L, *opts, 2);
return 0;
}
static int opts_index(lua_State *L) {
Expand All @@ -77,20 +81,15 @@ static int opts_newindex(lua_State *L) {
TomluaUserOpts *opts = (TomluaUserOpts *)lua_touserdata(L, lua_upvalueindex(1));
const char *key = luaL_checkstring(L, 2);
int value = lua_toboolean(L, 3);
lua_pop(L, 1);
lua_pushboolean(L, value);
int i = 0;
while (i < TOMLOPTS_LENGTH) {
if (strcmp(key, toml_opts_names[i]) == 0) {
(*opts)[i] = value;
break;
return 0;
}
i++;
}
if (i >= TOMLOPTS_LENGTH) return luaL_error(L, "invalid option '%s'", key);
// mirror into table so `print(inspect(opts))` shows it
lua_rawset(L, 1);
return 0;
return luaL_error(L, "invalid option '%s'", key);
}


Expand Down
4 changes: 2 additions & 2 deletions src/tomlua.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ int luaopen_tomlua(lua_State *L) {
{
TomluaUserOpts *uopts = lua_newuserdata(L, sizeof(TomluaUserOpts));
if (lua_istable(L, 2)) {
opts_parse(L, *uopts, 2, argtop + 1);
opts_parse(L, *uopts, 2);
} else {
opts_parse(L, *uopts, -1, argtop + 1);
opts_parse(L, *uopts, -1);
}
}
lua_pushvalue(L, -1);
Expand Down
44 changes: 44 additions & 0 deletions tests/opts_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
local define, test_dir = ...

local tomlua = require("tomlua")()

-- A mixed table that requires int_keys to encode
local mixed = { "a", "b", c = "d" }

define("changing current opts.int_keys = true", function()
tomlua.opts.int_keys = false
local _, err = tomlua.encode(mixed)
ok(err ~= nil, "encode without int_keys should error on mixed table")

tomlua.opts.int_keys = true
ok(tomlua.opts.int_keys == true, "opts.int_keys should read back as true")
local result, err2 = tomlua.encode(mixed)
ok(err2 == nil, "encode with int_keys=true should succeed")
ok(result ~= nil, "should produce output")
end)

define("opts.int_keys survives new copy", function()
tomlua.opts.fancy_dates = true
tomlua.opts.int_keys = true
local tomlua2 = tomlua{ fancy_dates = false, int_keys = false }
ok(tomlua.opts.int_keys == true, "int_keys should still be true after clone")
ok(tomlua.opts.fancy_dates == true, "fancy_dates should still be true after clone")
local result, err = tomlua2.encode(mixed)
ok(err ~= nil, "encode should fail with int_keys=false")
local result, err = tomlua.encode(mixed)
ok(err == nil, "encode should succeed with int_keys=true")
local opts = tomlua.opts()
ok(type(opts) == "table", "opts when called with no args should return a table")
end)

define("opts({ int_keys = true }) doesn't copy", function()
tomlua.opts.fancy_dates = true
tomlua.opts.int_keys = true
tomlua.opts{ fancy_dates = false, int_keys = false }
ok(tomlua.opts.int_keys == false, "int_keys should still be false after call")
ok(tomlua.opts.fancy_dates == false, "fancy_dates should be false after call")
local result, err = tomlua.encode(mixed)
ok(err ~= nil, "encode should fail with int_keys=false")
local opts = tomlua.opts()
ok(type(opts) == "table", "opts when called with no args should return a table")
end)