#include "common.h" /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Helper structs * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ struct argument_pair { honey_lua_type type; void* ptr; }; struct argument_list { unsigned int length; struct argument_pair* args; }; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Lua binding helper function declarations * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* string must be able to hold at least 16 characters. */ static const char* type_to_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, ...) { honey_result res; 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_); *string = malloc((string_size+1) * sizeof(char)); if (*string == NULL) res = HONEY_MEMORY_ALLOCATION_ERROR; else { vsnprintf(*string, string_size+1, format_string, args); res = HONEY_OK; } va_end(args); return res; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 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 bool check_arg_list(lua_State* L, struct argument_list arg_list) { struct argument_pair* args = arg_list.args; for (int i=0; iwindow, true); return 0; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Lua binding helper function definitions * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* string must be able to hold at least 16 characters. */ static const char* type_to_string(honey_lua_type type) { switch(type) { case HONEY_BOOLEAN: return "boolean"; case HONEY_INTEGER: return "integer"; case HONEY_NUMBER: return "number"; case HONEY_STRING: return "string"; case HONEY_FUNCTION: return "function"; case HONEY_TABLE: return "table"; case HONEY_NIL: return "nil"; case HONEY_USERDATA: return "userdata"; case HONEY_LIGHTUSERDATA: return "light userdata"; case HONEY_ANY: return "any"; default: return "ERROR"; } } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 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; } } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */