summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/04-term_spec.lua6
-rw-r--r--src/bitflags.c26
-rw-r--r--src/bitflags.h9
-rw-r--r--src/term.c29
4 files changed, 49 insertions, 21 deletions
diff --git a/spec/04-term_spec.lua b/spec/04-term_spec.lua
index c5b91e6..50fba45 100644
--- a/spec/04-term_spec.lua
+++ b/spec/04-term_spec.lua
@@ -246,7 +246,7 @@ describe("Terminal:", function()
flags.iflag = 0
assert.has.error(function()
system.tcsetattr(io.stdin, system.TCSANOW, flags)
- end, "bad argument #3 to 'tcsetattr' (table expected, got number)")
+ end, "bad argument #3, field 'iflag' must be a bitflag object")
end)
@@ -255,7 +255,7 @@ describe("Terminal:", function()
flags.oflag = 0
assert.has.error(function()
system.tcsetattr(io.stdin, system.TCSANOW, flags)
- end, "bad argument #3 to 'tcsetattr' (table expected, got number)")
+ end, "bad argument #3, field 'oflag' must be a bitflag object")
end)
@@ -264,7 +264,7 @@ describe("Terminal:", function()
flags.lflag = 0
assert.has.error(function()
system.tcsetattr(io.stdin, system.TCSANOW, flags)
- end, "bad argument #3 to 'tcsetattr' (table expected, got number)")
+ end, "bad argument #3, field 'lflag' must be a bitflag object")
end)
end)
diff --git a/src/bitflags.c b/src/bitflags.c
index 39f8af0..e397918 100644
--- a/src/bitflags.c
+++ b/src/bitflags.c
@@ -46,6 +46,32 @@ LSBF_BITFLAG lsbf_checkbitflags(lua_State *L, int index) {
return obj->flags;
}
+// Validates that the given index is a table containing a field 'fieldname'
+// which is a bitflag object and returns its value.
+// If the index is not a table or the field is not a bitflag object, a Lua
+// error is raised. If the bitflag is not present, the default value is returned.
+// The stack remains unchanged.
+LSBF_BITFLAG lsbf_checkbitflagsfield(lua_State *L, int index, const char *fieldname, LSBF_BITFLAG default_value) {
+ luaL_checktype(L, index, LUA_TTABLE);
+ lua_getfield(L, index, fieldname);
+
+ // if null, return default value
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1);
+ return default_value;
+ }
+
+ // check to bitflags
+ LS_BitFlags *obj = luaL_testudata(L, -1, BITFLAGS_MT_NAME);
+ if (obj == NULL) {
+ lua_pop(L, 1);
+ return luaL_error(L, "bad argument #%d, field '%s' must be a bitflag object", index, fieldname);
+ }
+ LSBF_BITFLAG value = obj->flags;
+ lua_pop(L, 1);
+ return value;
+}
+
/***
Creates a new bitflag object from the given value.
@function system.bitflag
diff --git a/src/bitflags.h b/src/bitflags.h
index 0e47246..f16b041 100644
--- a/src/bitflags.h
+++ b/src/bitflags.h
@@ -14,6 +14,15 @@
// The value will be left on the stack.
LSBF_BITFLAG lsbf_checkbitflags(lua_State *L, int index);
+
+// Validates that the given index is a table containing a field 'fieldname'
+// which is a bitflag object and returns its value.
+// If the index is not a table or the field is not a bitflag object, a Lua
+// error is raised. If the bitflag is not present, the default value is returned.
+// The stack remains unchanged.
+LSBF_BITFLAG lsbf_checkbitflagsfield(lua_State *L, int index, const char *fieldname, LSBF_BITFLAG default_value);
+
+
// Pushes a new bitflag object with the given value onto the stack.
// Might raise a Lua error if memory allocation fails.
void lsbf_pushbitflags(lua_State *L, LSBF_BITFLAG value);
diff --git a/src/term.c b/src/term.c
index 2b44b12..c0699f9 100644
--- a/src/term.c
+++ b/src/term.c
@@ -556,28 +556,13 @@ static int lst_tcsetattr(lua_State *L)
int r, i;
int fd = get_console_handle(L); // first is the console handle
int act = luaL_checkinteger(L, 2); // second is the action to take
- luaL_checktype(L, 3, LUA_TTABLE); // third is the termios table with fields
r = tcgetattr(fd, &t);
if (r == -1) return pusherror(L, NULL);
- lua_getfield(L, 3, "iflag");
- if (!lua_isnil(L, -1)) {
- t.c_iflag = lsbf_checkbitflags(L, -1);
- }
- lua_pop(L, 1);
-
- lua_getfield(L, 3, "oflag");
- if (!lua_isnil(L, -1)) {
- t.c_oflag = lsbf_checkbitflags(L, -1);
- }
- lua_pop(L, 1);
-
- lua_getfield(L, 3, "lflag");
- if (!lua_isnil(L, -1)) {
- t.c_lflag = lsbf_checkbitflags(L, -1);
- }
- lua_pop(L, 1);
+ t.c_iflag = lsbf_checkbitflagsfield(L, 3, "iflag", t.c_iflag);
+ t.c_oflag = lsbf_checkbitflagsfield(L, 3, "oflag", t.c_oflag);
+ t.c_lflag = lsbf_checkbitflagsfield(L, 3, "lflag", t.c_lflag);
// Skipping the others for now
@@ -596,6 +581,14 @@ static int lst_tcsetattr(lua_State *L)
r = tcsetattr(fd, act, &t);
if (r == -1) return pusherror(L, NULL);
+
+#else
+ // Windows does not have a tcsetattr function, but we check arguments anyway
+ get_console_handle(L, 1); // to validate args
+ luaL_checkinteger(L, 2);
+ lsbf_checkbitflagsfield(L, 3, "iflag", t.c_iflag);
+ lsbf_checkbitflagsfield(L, 3, "oflag", t.c_iflag);
+ lsbf_checkbitflagsfield(L, 3, "lflag", t.c_iflag);
#endif
lua_pushboolean(L, 1);