void test_arguments(void) { serial_t serial; ptest(); /* Invalid data bits (4 and 9) */ passert(serial_open_advanced(&serial, device, 115200, 4, PARITY_NONE, 1, false, false) == SERIAL_ERROR_ARG); passert(serial_open_advanced(&serial, device, 115200, 9, PARITY_NONE, 1, false, false) == SERIAL_ERROR_ARG); /* Invalid parity */ passert(serial_open_advanced(&serial, device, 115200, 8, PARITY_EVEN+1, 1, false, false) == SERIAL_ERROR_ARG); /* Invalid stopbits */ passert(serial_open_advanced(&serial, device, 115200, 8, PARITY_NONE, 0, false, false) == SERIAL_ERROR_ARG); passert(serial_open_advanced(&serial, device, 115200, 8, PARITY_NONE, 3, false, false) == SERIAL_ERROR_ARG); /* Everything else is fair game, although termios might not like it. */ }
static int lua_serial_open(lua_State *L) { serial_t *serial; const char *device; uint32_t baudrate; int databits; serial_parity_t parity; int stopbits; bool xonxoff; bool rtscts; int ret; serial = luaL_checkudata(L, 1, "periphery.Serial"); /* Initialize file descriptor to an invalid value, in case an error occurs * below and gc later close()'s this object. */ serial->fd = -1; /* Default settings of optional arguments */ databits = 8; parity = PARITY_NONE; stopbits = 1; xonxoff = false; rtscts = false; /* Arguments passed in table form */ if (lua_istable(L, 2)) { lua_getfield(L, 2, "device"); if (!lua_isstring(L, -1)) return lua_serial_error(L, SERIAL_ERROR_ARG, 0, "Error: invalid type on table argument 'device', should be string"); lua_getfield(L, 2, "baudrate"); if (!lua_isnumber(L, -1)) return lua_serial_error(L, SERIAL_ERROR_ARG, 0, "Error: invalid type on table argument 'baudrate', should be number"); device = lua_tostring(L, -2); baudrate = lua_tounsigned(L, -1); /* Optional databits */ lua_getfield(L, 2, "databits"); if (lua_isnumber(L, -1)) databits = lua_tounsigned(L, -1); else if (!lua_isnil(L, -1)) return lua_serial_error(L, SERIAL_ERROR_ARG, 0, "Error: invalid type of table argument 'databits', should be number"); /* Optional parity */ lua_getfield(L, 2, "parity"); if (lua_isstring(L, -1)) { const char *s = lua_tostring(L, -1); if (strcmp(s, "none") == 0) parity = PARITY_NONE; else if (strcmp(s, "even") == 0) parity = PARITY_EVEN; else if (strcmp(s, "odd") == 0) parity = PARITY_ODD; else return lua_serial_error(L, SERIAL_ERROR_ARG, 0, "Error: invalid parity, should be 'none', 'even', or 'odd'"); } else if (!lua_isnil(L, -1)) return lua_serial_error(L, SERIAL_ERROR_ARG, 0, "Error: invalid type of table argument 'parity', should be string"); /* Optional stopbits */ lua_getfield(L, 2, "stopbits"); if (lua_isnumber(L, -1)) stopbits = lua_tounsigned(L, -1); else if (!lua_isnil(L, -1)) return lua_serial_error(L, SERIAL_ERROR_ARG, 0, "Error: invalid type of table argument 'stopbits', should be number"); /* Optional xonxoff */ lua_getfield(L, 2, "xonxoff"); if (lua_isboolean(L, -1)) xonxoff = lua_toboolean(L, -1); else if (!lua_isnil(L, -1)) return lua_serial_error(L, SERIAL_ERROR_ARG, 0, "Error: invalid type of table argument 'xonxoff', should be boolean"); /* Optional rtscts */ lua_getfield(L, 2, "rtscts"); if (lua_isboolean(L, -1)) rtscts = lua_toboolean(L, -1); else if (!lua_isnil(L, -1)) return lua_serial_error(L, SERIAL_ERROR_ARG, 0, "Error: invalid type of table argument 'rtscts', should be boolean"); /* Arguments passed normally */ } else { lua_serial_checktype(L, 2, LUA_TSTRING); lua_serial_checktype(L, 3, LUA_TNUMBER); device = lua_tostring(L, 2); baudrate = lua_tounsigned(L, 3); } if ((ret = serial_open_advanced(serial, device, baudrate, databits, parity, stopbits, xonxoff, rtscts)) < 0) return lua_serial_error(L, ret, serial_errno(serial), serial_errmsg(serial)); return 0; }