summaryrefslogtreecommitdiff
path: root/src/honey_lua.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/honey_lua.c')
-rw-r--r--src/honey_lua.c489
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;
+ }
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */