diff options
Diffstat (limited to 'degesch.c')
-rw-r--r-- | degesch.c | 188 |
1 files changed, 94 insertions, 94 deletions
@@ -7349,6 +7349,100 @@ lua_cache_invalidate (lua_State *L, void *object) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/// Append a traceback to all errors so that we can later extract it +static int +lua_plugin_error_handler (lua_State *L) +{ + luaL_traceback (L, L, luaL_checkstring (L, 1), 1); + return 1; +} + +static bool +lua_plugin_process_error (struct lua_plugin *self, const char *message, + struct error **e) +{ + struct str_vector v; + str_vector_init (&v); + cstr_split_ignore_empty (message, '\n', &v); + + if (v.len < 2) + error_set (e, "%s", message); + else + { + error_set (e, "%s", v.vector[0]); + log_global_debug (self->ctx, "Lua: plugin \"#s\": #s", + self->super.name, v.vector[1]); + for (size_t i = 2; i < v.len; i++) + log_global_debug (self->ctx, " #s", v.vector[i]); + } + + str_vector_free (&v); + return false; +} + +/// Call a Lua function and process errors using our special error handler +static bool +lua_plugin_call (struct lua_plugin *self, + int n_params, int n_results, struct error **e) +{ + lua_State *L = self->L; + + // We need to pop the error handler at the end + lua_pushcfunction (L, lua_plugin_error_handler); + int error_handler_idx = -n_params - 2; + lua_insert (L, error_handler_idx); + + if (!lua_pcall (L, n_params, n_results, error_handler_idx)) + { + lua_remove (L, -n_results - 1); + return true; + } + + (void) lua_plugin_process_error (self, lua_tostring (L, -1), e); + lua_pop (L, 2); + return false; +} + +/// Convenience function; replaces the "original" string or produces an error +static bool +lua_plugin_handle_string_filter_result (struct lua_plugin *self, + char **original, bool utf8, struct error **e) +{ + lua_State *L = self->L; + if (lua_isnil (L, -1)) + { + free (*original); + *original = NULL; + return true; + } + if (!lua_isstring (L, -1)) + FAIL ("must return either a string or nil"); + + size_t len; + const char *processed = lua_tolstring (L, -1, &len); + if (utf8 && !utf8_validate (processed, len)) + FAIL ("must return valid UTF-8"); + + // Only replace the string if it's different + if (strcmp (processed, *original)) + { + free (*original); + *original = xstrdup (processed); + } + return true; +} + +static void +lua_plugin_log_error + (struct lua_plugin *self, const char *where, struct error *error) +{ + log_global_error (self->ctx, "Lua: plugin \"#s\": #s: #s", + self->super.name, where, error->message); + error_free (error); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #define XLUA_BUFFER_METATABLE "buffer" ///< Identifier for the Lua metatable struct lua_buffer @@ -7587,100 +7681,6 @@ static luaL_Reg lua_hook_table[] = // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/// Append a traceback to all errors so that we can later extract it -static int -lua_plugin_error_handler (lua_State *L) -{ - luaL_traceback (L, L, luaL_checkstring (L, 1), 1); - return 1; -} - -static bool -lua_plugin_process_error (struct lua_plugin *self, const char *message, - struct error **e) -{ - struct str_vector v; - str_vector_init (&v); - cstr_split_ignore_empty (message, '\n', &v); - - if (v.len < 2) - error_set (e, "%s", message); - else - { - error_set (e, "%s", v.vector[0]); - log_global_debug (self->ctx, "Lua: plugin \"#s\": #s", - self->super.name, v.vector[1]); - for (size_t i = 2; i < v.len; i++) - log_global_debug (self->ctx, " #s", v.vector[i]); - } - - str_vector_free (&v); - return false; -} - -/// Call a Lua function and process errors using our special error handler -static bool -lua_plugin_call (struct lua_plugin *self, - int n_params, int n_results, struct error **e) -{ - lua_State *L = self->L; - - // We need to pop the error handler at the end - lua_pushcfunction (L, lua_plugin_error_handler); - int error_handler_idx = -n_params - 2; - lua_insert (L, error_handler_idx); - - if (!lua_pcall (L, n_params, n_results, error_handler_idx)) - { - lua_remove (L, -n_results - 1); - return true; - } - - (void) lua_plugin_process_error (self, lua_tostring (L, -1), e); - lua_pop (L, 2); - return false; -} - -/// Convenience function; replaces the "original" string or produces an error -static bool -lua_plugin_handle_string_filter_result (struct lua_plugin *self, - char **original, bool utf8, struct error **e) -{ - lua_State *L = self->L; - if (lua_isnil (L, -1)) - { - free (*original); - *original = NULL; - return true; - } - if (!lua_isstring (L, -1)) - FAIL ("must return either a string or nil"); - - size_t len; - const char *processed = lua_tolstring (L, -1, &len); - if (utf8 && !utf8_validate (processed, len)) - FAIL ("must return valid UTF-8"); - - // Only replace the string if it's different - if (strcmp (processed, *original)) - { - free (*original); - *original = xstrdup (processed); - } - return true; -} - -static void -lua_plugin_log_error - (struct lua_plugin *self, const char *where, struct error *error) -{ - log_global_error (self->ctx, "Lua: plugin \"#s\": #s: #s", - self->super.name, where, error->message); - error_free (error); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static char * lua_input_hook_filter (struct input_hook *self, struct buffer *buffer, char *input) |