diff options
Diffstat (limited to 'src/honey_lua.c')
-rw-r--r-- | src/honey_lua.c | 489 |
1 files changed, 257 insertions, 232 deletions
diff --git a/src/honey_lua.c b/src/honey_lua.c index f427969..7730809 100644 --- a/src/honey_lua.c +++ b/src/honey_lua.c @@ -1,6 +1,31 @@ #include "common.h" -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Lua binding helper function definitions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* string must be able to hold at least 16 characters. */ +static void type_to_string(char* string, + honey_lua_type type); + +static bool check_argument(lua_State* L, + honey_lua_type type, + int index); + +static void get_argument(lua_State* L, + void* destination, + honey_lua_type type, + int index); + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * String wrangling helpers + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ honey_result honey_format_string(char** string, char* format_string, @@ -28,13 +53,46 @@ honey_result honey_format_string(char** string, /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +void honey_lua_throw_error(lua_State* L, + char* format_string, + ...) +{ + honey_result result; + va_list args, args_; + va_start(args, format_string); + va_copy(args_, args); + + int string_size = vsnprintf(NULL, 0, format_string, args_); + va_end(args_); + + char* string = malloc((string_size + 1) * sizeof(char)); + if (string == NULL) + lua_pushstring(L, "there was an error allocating memory for an error message"); + else { + vsnprintf(string, string_size + 1, format_string, args); + lua_pushstring(L, string); + free(string); + } + lua_error(L); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Argument parsing functions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + static void honey_lua_arg_error(lua_State* L, - char* expected_type, + honey_lua_type type, int position) { + char expected_type[16]; + type_to_string(expected_type, type); + char* error_message; honey_result result; - char* got_type = lua_typename(L, lua_type(L, position)); + char* got_type = (char*) lua_typename(L, lua_type(L, position)); result = honey_format_string(&error_message, "bad argument in position %d: " "expected %s, but got %s instead.", @@ -53,245 +111,29 @@ static void honey_lua_arg_error(lua_State* L, /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -void honey_lua_parse_arguments(lua_State* L, int n, ...) +int honey_lua_parse_arguments(lua_State* L, int n, ...) { va_list args; va_start(args, n); for (int i=1; i<=n; i++) { - honey_lua_type expected_type = va_arg(args, honey_lua_type); - - switch (expected_type) { - case HONEY_BOOLEAN: - if (!lua_isboolean(L, i)) - honey_lua_arg_error(L, "boolean", i); - { - bool* result = va_arg(args, bool*); - *result = lua_toboolean(L, i); - } - break; - - case HONEY_INTEGER: - if (!lua_isnumber(L, i)) - honey_lua_arg_error(L, "integer", i); - { - int* result = va_arg(args, int*); - *result = lua_tointeger(L, i); - } - break; - - case HONEY_NUMBER: - if (!lua_isnumber(L, i)) - honey_lua_arg_error(L, "number", i); - { - float* result = va_arg(args, float*); - *result = lua_tonumber(L, i); - } - break; - - case HONEY_STRING: - if (!lua_isstring(L, i)) - honey_lua_arg_error(L, "string", i); - { - char** result = va_arg(args, char**); - *result = lua_tostring(L, i); - } - break; - - case HONEY_TABLE: - if (!lua_istable(L, i)) - honey_lua_arg_error(L, "table", i); - break; - - case HONEY_FUNCTION: - if (!lua_isfunction(L, i)) - honey_lua_arg_error(L, "function", i); - break; - - case HONEY_NIL: - if (!lua_isnil(L, i)) - honey_lua_arg_error(L, "nil", i); - break; - - case HONEY_USERDATA: - if (!lua_isuserdata(L, i)) - honey_lua_arg_error(L, "userdata", i); - { - void** result = va_arg(args, void**); - *result = lua_touserdata(L, i); - } - break; - - case HONEY_LIGHTUSERDATA: - if (!lua_isuserdata(L, i)) - honey_lua_arg_error(L, "light userdata", i); - { - void** result = va_arg(args, void**); - *result = lua_touserdata(L, i); - } - break; - - case HONEY_ANY: - break; - - default: - /* should never get here! */ - break; - } - } - - va_end(args); -} + honey_lua_type type = va_arg(args, honey_lua_type); + void* destination = va_arg(args, void*); + if (!check_argument(L, type, i)) + honey_lua_arg_error(L, type, i); -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -bool honey_lua_validate_types(lua_State* L, - unsigned int n_types, - ...) -{ - va_list args; - va_start(args, n_types); - - for (int i=0; i<n_types; i++) { - honey_lua_type expected_type = va_arg(args, honey_lua_type); - honey_result result; - char* error_message; - - switch(expected_type) { - case HONEY_BOOLEAN: - if (!lua_isboolean(L, i+1)) { - result = honey_format_string(&error_message, - "Expected boolean in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected boolean; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_INTEGER: - case HONEY_NUMBER: - if (!lua_isnumber(L, i+1)) { - result = honey_format_string(&error_message, - "Expected number in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected number; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_STRING: - if (!lua_isstring(L, i+1)) { - result = honey_format_string(&error_message, - "Expected string in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected string; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_FUNCTION: - if (!lua_isfunction(L, i+1)) { - result = honey_format_string(&error_message, - "Expected function in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected function; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_TABLE: - if (!lua_istable(L, i+1)) { - result = honey_format_string(&error_message, - "Expected table in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected table; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_NIL: - if (!lua_isnil(L, i+1)) { - result = honey_format_string(&error_message, - "Expected nil in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected nil; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_USERDATA: - if (!lua_isuserdata(L, i+1)) { - result = honey_format_string(&error_message, - "Expected userdata in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected userdata; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_LIGHTUSERDATA: - if (!lua_islightuserdata(L, i+1)) { - result = honey_format_string(&error_message, - "Expected C pointer in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected C pointer; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_ANY: - break; - - default: - break; - } + get_argument(L, destination, type, i); } - + va_end(args); - return true; } -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Table creation functions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ void honey_lua_create_table(lua_State* L, honey_lua_element* elements, @@ -407,3 +249,186 @@ int honey_exit(lua_State* L) glfwSetWindowShouldClose(info->window, true); return 0; } + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Lua binding helper functions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* string must be able to hold at least 16 characters. */ +static void type_to_string(char* string, + honey_lua_type type) +{ + switch(type) { + case HONEY_BOOLEAN: + memcpy(string, "boolean", 8); + break; + + case HONEY_INTEGER: + memcpy(string, "integer", 8); + break; + + case HONEY_NUMBER: + memcpy(string, "number", 7); + break; + + case HONEY_STRING: + memcpy(string, "string", 7); + break; + + case HONEY_FUNCTION: + memcpy(string, "function", 9); + break; + + case HONEY_TABLE: + memcpy(string, "table", 6); + break; + + case HONEY_NIL: + memcpy(string, "nil", 4); + break; + + case HONEY_USERDATA: + memcpy(string, "userdata", 9); + break; + + case HONEY_LIGHTUSERDATA: + memcpy(string, "light userdata", 16); + break; + + case HONEY_ANY: + memcpy(string, "any", 4); + break; + + default: + break; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static bool check_argument(lua_State* L, + honey_lua_type type, + int index) +{ + switch(type) { + case HONEY_BOOLEAN: + if (!lua_isboolean(L, index)) + return false; + break; + + case HONEY_INTEGER: + case HONEY_NUMBER: + if (!lua_isnumber(L, index)) + return false; + break; + + case HONEY_STRING: + if (!lua_isstring(L, index)) + return false; + break; + + case HONEY_FUNCTION: + if (!lua_isfunction(L, index)) + return false; + break; + + case HONEY_TABLE: + if (!lua_istable(L, index)) + return false; + break; + + case HONEY_NIL: + if (!lua_isnil(L, index)) + return false; + break; + + case HONEY_USERDATA: + if (!lua_isuserdata(L, index)) + return false; + break; + + case HONEY_LIGHTUSERDATA: + if (!lua_islightuserdata(L, index)) + return false; + break; + + default: + break; + } + + + return true; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static void get_argument(lua_State* L, + void* destination, + honey_lua_type type, + int index) +{ + switch (type) { + case HONEY_BOOLEAN: + { + bool* result = destination; + *result = lua_toboolean(L, index); + } + break; + + case HONEY_INTEGER: + { + int* result = destination; + *result = lua_tointeger(L, index); + } + break; + + case HONEY_NUMBER: + { + float* result = destination; + *result = lua_tonumber(L, index); + } + break; + + case HONEY_STRING: + { + char** result = destination; + *result = (char*) lua_tostring(L, index); + } + break; + + case HONEY_TABLE: + break; + + case HONEY_FUNCTION: + break; + + case HONEY_NIL: + break; + + case HONEY_USERDATA: + { + void** result = destination; + *result = lua_touserdata(L, index); + } + break; + + case HONEY_LIGHTUSERDATA: + { + void** result = destination; + *result = lua_touserdata(L, index); + } + break; + + case HONEY_ANY: + break; + + default: + /* should never get here! */ + break; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ |