From 0fa0a59c8ba08557238e9a584ebccf6e41a502db Mon Sep 17 00:00:00 2001 From: Dave Date: Fri, 30 Dec 2022 11:52:47 +0000 Subject: [PATCH 001/148] Minor typos in init text --- data/core/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/core/init.lua b/data/core/init.lua index da016774..89ac7ec4 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -594,7 +594,7 @@ local config = require "core.config" -- "^/build.*/" match any top level directory whose name begins with "build" -- "^/subprojects/.+/" match any directory inside a top-level folder named "subprojects". --- You may activate some plugins on a pre-project base to override the user's settings. +-- You may activate some plugins on a per-project basis to override the user's settings. -- config.plugins.trimwitespace = true ]]) init_file:close() From bd4e64cc7e73033560e46ab10629ddadfecf5beb Mon Sep 17 00:00:00 2001 From: Guldoman Date: Mon, 2 Jan 2023 03:12:14 +0100 Subject: [PATCH 002/148] Allow command buffer to be expanded (#1297) --- src/rencache.c | 42 ++++++++++++++++++++++++++++++++++-------- src/renderer.c | 5 +++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/rencache.c b/src/rencache.c index c9b1885a..12c2a33c 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -26,7 +26,8 @@ #define CELLS_X 80 #define CELLS_Y 50 #define CELL_SIZE 96 -#define COMMAND_BUF_SIZE (1024 * 512) +#define CMD_BUF_RESIZE_RATE 1.2 +#define CMD_BUF_INIT_SIZE (1024 * 512) #define COMMAND_BARE_SIZE offsetof(Command, text) enum { SET_CLIP, DRAW_TEXT, DRAW_RECT }; @@ -48,7 +49,9 @@ static unsigned cells_buf2[CELLS_X * CELLS_Y]; static unsigned *cells_prev = cells_buf1; static unsigned *cells = cells_buf2; static RenRect rect_buf[CELLS_X * CELLS_Y / 2]; -static char command_buf[COMMAND_BUF_SIZE]; +size_t command_buf_size = 0; +uint8_t *command_buf = NULL; +static bool resize_issue; static int command_buf_idx; static RenRect screen_rect; static bool show_debug; @@ -96,16 +99,38 @@ static RenRect merge_rects(RenRect a, RenRect b) { return (RenRect) { x1, y1, x2 - x1, y2 - y1 }; } +static bool expand_command_buffer() { + size_t new_size = command_buf_size * CMD_BUF_RESIZE_RATE; + if (new_size == 0) { + new_size = CMD_BUF_INIT_SIZE; + } + uint8_t *new_command_buf = realloc(command_buf, new_size); + if (!new_command_buf) { + return false; + } + command_buf_size = new_size; + command_buf = new_command_buf; + return true; +} static Command* push_command(int type, int size) { - size_t alignment = alignof(max_align_t) - 1; - size = (size + alignment) & ~alignment; - Command *cmd = (Command*) (command_buf + command_buf_idx); - int n = command_buf_idx + size; - if (n > COMMAND_BUF_SIZE) { - fprintf(stderr, "Warning: (" __FILE__ "): exhausted command buffer\n"); + if (resize_issue) { + // Don't push new commands as we had problems resizing the command buffer. + // Let's wait for the next frame. return NULL; } + size_t alignment = alignof(max_align_t) - 1; + size = (size + alignment) & ~alignment; + int n = command_buf_idx + size; + while (n > command_buf_size) { + if (!expand_command_buffer()) { + fprintf(stderr, "Warning: (" __FILE__ "): unable to resize command buffer (%ld)\n", + (size_t)(command_buf_size * CMD_BUF_RESIZE_RATE)); + resize_issue = true; + return NULL; + } + } + Command *cmd = (Command*) (command_buf + command_buf_idx); command_buf_idx = n; memset(cmd, 0, size); cmd->type = type; @@ -175,6 +200,7 @@ void rencache_invalidate(void) { void rencache_begin_frame() { /* reset all cells if the screen width/height has changed */ int w, h; + resize_issue = false; ren_get_size(&w, &h); if (screen_rect.width != w || h != screen_rect.height) { screen_rect.width = w; diff --git a/src/renderer.c b/src/renderer.c index c93569ce..9fe629f8 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -507,8 +507,13 @@ void ren_draw_rect(RenRect rect, RenColor color) { /*************** Window Management ****************/ void ren_free_window_resources() { + extern uint8_t *command_buf; + extern size_t command_buf_size; renwin_free(&window_renderer); SDL_FreeSurface(draw_rect_surface); + free(command_buf); + command_buf = NULL; + command_buf_size = 0; } void ren_init(SDL_Window *win) { From 69ce580970550bf4bfaa60646a61e511df90f71e Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Wed, 4 Jan 2023 23:46:08 +0800 Subject: [PATCH 003/148] do not allow users to create an empty font group (#1303) --- src/api/renderer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/api/renderer.c b/src/api/renderer.c index 261fc26a..ae2c7ae0 100644 --- a/src/api/renderer.c +++ b/src/api/renderer.c @@ -145,6 +145,8 @@ static int f_font_group(lua_State* L) { luaL_checktype(L, 1, LUA_TTABLE); table_size = lua_rawlen(L, 1); + if (table_size <= 0) + return luaL_error(L, "failed to create font group: table is empty"); if (table_size > FONT_FALLBACK_MAX) return luaL_error(L, "failed to create font group: table size too large"); From d755fa6fbaf847929e99440fdc38fb93f04db53b Mon Sep 17 00:00:00 2001 From: Julien Voisin Date: Thu, 5 Jan 2023 21:46:26 +0100 Subject: [PATCH 004/148] Make api_require's nodes const (#1296) --- src/api/system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/system.c b/src/api/system.c index 70d02156..5e55acce 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -916,7 +916,7 @@ typedef struct lua_function_node { #define P(FUNC) { "lua_" #FUNC, (fptr)(lua_##FUNC) } #define U(FUNC) { "luaL_" #FUNC, (fptr)(luaL_##FUNC) } static void* api_require(const char* symbol) { - static lua_function_node nodes[] = { + static const lua_function_node nodes[] = { P(atpanic), P(checkstack), P(close), P(concat), P(copy), P(createtable), P(dump), P(error), P(gc), P(getallocf), P(getfield), From d06c9f401ca84ea4315176385e00e221cb8de37f Mon Sep 17 00:00:00 2001 From: Julien Voisin Date: Thu, 5 Jan 2023 21:48:01 +0100 Subject: [PATCH 005/148] Fix a memory leak (#1305) `font` was not freed upon error. --- src/renderer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/renderer.c b/src/renderer.c index 9fe629f8..4319f042 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -281,8 +281,10 @@ RenFont* ren_font_load(const char* path, float size, ERenFontAntialiasing antial font->underline_thickness = (unsigned short)((face->underline_thickness / (float)face->units_per_EM) * font->size); if(!font->underline_thickness) font->underline_thickness = ceil((double) font->height / 14.0); - if (FT_Load_Char(face, ' ', font_set_load_options(font))) + if (FT_Load_Char(face, ' ', font_set_load_options(font))) { + free(font); goto failure; + } font->space_advance = face->glyph->advance.x / 64.0f; font->tab_advance = font->space_advance * 2; return font; From d86413cc306a464e972b0b7cde20bb417431b89e Mon Sep 17 00:00:00 2001 From: Julien Voisin Date: Thu, 5 Jan 2023 21:48:49 +0100 Subject: [PATCH 006/148] Don't set a value twice (#1306) --- src/api/utf8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/utf8.c b/src/api/utf8.c index 643cb2cc..b23b4cfc 100644 --- a/src/api/utf8.c +++ b/src/api/utf8.c @@ -377,7 +377,7 @@ static int Lutf8_codepoint (lua_State *L) { luaL_checkstack(L, n, "string slice too long"); n = 0; /* count the number of returns */ se = s + pose; /* string end */ - for (n = 0, s += posi - 1; s < se;) { + for (s += posi - 1; s < se;) { utfint code = 0; s = utf8_safe_decode(L, s, &code); if (!lax && utf8_invalid(code)) From 138cea45d54518610c2878730cf89b7237e51b31 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Thu, 5 Jan 2023 21:59:15 +0100 Subject: [PATCH 007/148] Make `dirwatch` sorting compatible with what `file_bisect` expects (#1300) The result of `a.filename < b.filename` is sometimes different from `system.path_compare(a.filename, a.type, b.filename, b.type)` which causes issues to `file_bisect`, as it expects the sorting to be done with `system.path_compare`. --- data/core/dirwatch.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/core/dirwatch.lua b/data/core/dirwatch.lua index 059291f1..e3b6d61c 100644 --- a/data/core/dirwatch.lua +++ b/data/core/dirwatch.lua @@ -166,7 +166,7 @@ end local function compare_file(a, b) - return a.filename < b.filename + return system.path_compare(a.filename, a.type, b.filename, b.type) end From 1ab320bb9bdd147851b7dcc9f4e91e6d0298a1bd Mon Sep 17 00:00:00 2001 From: Julien Voisin Date: Thu, 5 Jan 2023 21:59:45 +0100 Subject: [PATCH 008/148] Handle readlink errors (#1292) --- src/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 10910056..19b7d40f 100644 --- a/src/main.c +++ b/src/main.c @@ -36,8 +36,9 @@ static void get_exe_filename(char *buf, int sz) { buf[len] = '\0'; #elif __linux__ char path[] = "/proc/self/exe"; - int len = readlink(path, buf, sz - 1); - buf[len] = '\0'; + ssize_t len = readlink(path, buf, sz - 1); + if (len > 0) + buf[len] = '\0'; #elif __APPLE__ /* use realpath to resolve a symlink if the process was launched from one. ** This happens when Homebrew installs a cack and creates a symlink in From f00f41b46844b96f5ad85cbe0dcee1e6a9a29568 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Thu, 5 Jan 2023 22:02:12 +0100 Subject: [PATCH 009/148] `linewrapping`: Disable horizontal scrolling when enabled (#1309) --- data/plugins/linewrapping.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data/plugins/linewrapping.lua b/data/plugins/linewrapping.lua index cbfa3158..b287c523 100644 --- a/data/plugins/linewrapping.lua +++ b/data/plugins/linewrapping.lua @@ -355,6 +355,12 @@ function DocView:get_scrollable_size() return self:get_line_height() * (get_total_wrapped_lines(self) - 1) + self.size.y end +local old_get_h_scrollable_size = DocView.get_h_scrollable_size +function DocView:get_h_scrollable_size(...) + if self.wrapping_enabled then return 0 end + return old_get_h_scrollable_size(self, ...) +end + local old_new = DocView.new function DocView:new(doc) old_new(self, doc) From 60f0e3f3da3b80293b39d8c37e0e11e5d0d36b61 Mon Sep 17 00:00:00 2001 From: jgmdev Date: Fri, 6 Jan 2023 11:43:14 -0400 Subject: [PATCH 010/148] Packaging Scripts: updated widgets install location --- scripts/common.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/common.sh b/scripts/common.sh index dab1acfa..58fbd312 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -27,7 +27,8 @@ addons_download() { -o "${build_dir}/lite-xl-widgets.zip" unzip "${build_dir}/lite-xl-widgets.zip" -d "${build_dir}" - mv "${build_dir}/lite-xl-widgets-master" "${build_dir}/third/data/widget" + mkdir -p "${build_dir}/third/data/libraries" + mv "${build_dir}/lite-xl-widgets-master" "${build_dir}/third/data/libraries/widget" # Downlaod thirdparty plugins curl --insecure \ @@ -45,7 +46,7 @@ addons_install() { local build_dir="$1" local data_dir="$2" - for module_name in colors widget; do + for module_name in colors libraries; do cp -r "${build_dir}/third/data/$module_name" "${data_dir}" done From 4b6134a8398086e1427a269e793885d2e4c43a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jefferson=20Gonz=C3=A1lez?= Date: Fri, 6 Jan 2023 14:22:55 -0400 Subject: [PATCH 011/148] plugin api: added missing luaL_typeerror (#1313) --- resources/lite_xl_plugin_api.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/lite_xl_plugin_api.h b/resources/lite_xl_plugin_api.h index 11467e65..5337d8ae 100644 --- a/resources/lite_xl_plugin_api.h +++ b/resources/lite_xl_plugin_api.h @@ -540,6 +540,7 @@ static void *(*luaL_testudata) (lua_State *L, int ud, const char *tname); static void *(*luaL_checkudata) (lua_State *L, int ud, const char *tname); static void (*luaL_where) (lua_State *L, int lvl); static int (*luaL_error) (lua_State *L, const char *fmt, ...); +static int (*luaL_typeerror) (lua_State *L, int narg, const char *tname); static int (*luaL_checkoption) (lua_State *L, int narg, const char *def, const char *const lst[]); static int (*luaL_fileresult) (lua_State *L, int stat, const char *fname); static int (*luaL_execresult) (lua_State *L, int stat); @@ -611,6 +612,7 @@ static void * __lite_xl_fallback_luaL_testudata (lua_State *L, int ud, const cha static void * __lite_xl_fallback_luaL_checkudata (lua_State *L, int ud, const char *tname) { fputs("warning: luaL_checkudata is a stub", stderr); } static void __lite_xl_fallback_luaL_where (lua_State *L, int lvl) { fputs("warning: luaL_where is a stub", stderr); } static int __lite_xl_fallback_luaL_error (lua_State *L, const char *fmt, ...) { fputs("warning: luaL_error is a stub", stderr); } +static int __lite_xl_fallback_luaL_typeerror (lua_State *L, int narg, const char *tname) { fputs("warning: luaL_typeerror is a stub", stderr); } static int __lite_xl_fallback_luaL_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]) { fputs("warning: luaL_checkoption is a stub", stderr); } static int __lite_xl_fallback_luaL_fileresult (lua_State *L, int stat, const char *fname) { fputs("warning: luaL_fileresult is a stub", stderr); } static int __lite_xl_fallback_luaL_execresult (lua_State *L, int stat) { fputs("warning: luaL_execresult is a stub", stderr); } @@ -752,6 +754,7 @@ static void lite_xl_plugin_init(void *XL) { IMPORT_SYMBOL(luaL_checkudata, void *, lua_State *L, int ud, const char *tname); IMPORT_SYMBOL(luaL_where, void , lua_State *L, int lvl); IMPORT_SYMBOL(luaL_error, int , lua_State *L, const char *fmt, ...); + IMPORT_SYMBOL(luaL_typeerror, int , lua_State *L, int narg, const char *tname); IMPORT_SYMBOL(luaL_checkoption, int , lua_State *L, int narg, const char *def, const char *const lst[]); IMPORT_SYMBOL(luaL_fileresult, int , lua_State *L, int stat, const char *fname); IMPORT_SYMBOL(luaL_execresult, int , lua_State *L, int stat); From f5a224999ac8fa296eb04bd90ae5b401649f88d5 Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 6 Jan 2023 19:31:44 +0100 Subject: [PATCH 012/148] defer lua error until after cleanup (#1310) --- src/api/process.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/api/process.c b/src/api/process.c index 93759517..60efe5f9 100644 --- a/src/api/process.c +++ b/src/api/process.c @@ -173,11 +173,8 @@ static int process_start(lua_State* L) { lua_getfield(L, 2, "stderr"); new_fds[STDERR_FD] = luaL_optnumber(L, -1, STDERR_FD); for (int stream = STDIN_FD; stream <= STDERR_FD; ++stream) { if (new_fds[stream] > STDERR_FD || new_fds[stream] < REDIRECT_PARENT) { - for (size_t i = 0; i < env_len; ++i) { - free((char*)env_names[i]); - free((char*)env_values[i]); - } - retval = luaL_error(L, "redirect to handles, FILE* and paths are not supported"); + lua_pushfstring(L, "redirect to handles, FILE* and paths are not supported"); + retval = -1; goto cleanup; } } @@ -210,18 +207,21 @@ static int process_start(lua_State* L) { self->child_pipes[i][0] = CreateNamedPipeA(pipeNameBuffer, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, 1, READ_BUF_SIZE, READ_BUF_SIZE, 0, NULL); if (self->child_pipes[i][0] == INVALID_HANDLE_VALUE) { - retval = luaL_error(L, "Error creating read pipe: %d.", GetLastError()); + lua_pushfstring(L, "Error creating read pipe: %d.", GetLastError()); + retval = -1; goto cleanup; } self->child_pipes[i][1] = CreateFileA(pipeNameBuffer, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (self->child_pipes[i][1] == INVALID_HANDLE_VALUE) { CloseHandle(self->child_pipes[i][0]); - retval = luaL_error(L, "Error creating write pipe: %d.", GetLastError()); + lua_pushfstring(L, "Error creating write pipe: %d.", GetLastError()); + retval = -1; goto cleanup; } if (!SetHandleInformation(self->child_pipes[i][i == STDIN_FD ? 1 : 0], HANDLE_FLAG_INHERIT, 0) || !SetHandleInformation(self->child_pipes[i][i == STDIN_FD ? 0 : 1], HANDLE_FLAG_INHERIT, 1)) { - retval = luaL_error(L, "Error inheriting pipes: %d.", GetLastError()); + lua_pushfstring(L, "Error inheriting pipes: %d.", GetLastError()); + retval = -1; goto cleanup; } } @@ -284,7 +284,8 @@ static int process_start(lua_State* L) { if (env_len > 0) MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, environmentBlock, offset, (LPWSTR)wideEnvironmentBlock, sizeof(wideEnvironmentBlock)); if (!CreateProcess(NULL, commandLine, NULL, NULL, true, (detach ? DETACHED_PROCESS : CREATE_NO_WINDOW) | CREATE_UNICODE_ENVIRONMENT, env_len > 0 ? wideEnvironmentBlock : NULL, cwd, &siStartInfo, &self->process_information)) { - retval = luaL_error(L, "Error creating a process: %d.", GetLastError()); + lua_pushfstring(L, "Error creating a process: %d.", GetLastError()); + retval = -1; goto cleanup; } self->pid = (long)self->process_information.dwProcessId; @@ -294,13 +295,15 @@ static int process_start(lua_State* L) { #else for (int i = 0; i < 3; ++i) { // Make only the parents fd's non-blocking. Children should block. if (pipe(self->child_pipes[i]) || fcntl(self->child_pipes[i][i == STDIN_FD ? 1 : 0], F_SETFL, O_NONBLOCK) == -1) { - retval = luaL_error(L, "Error creating pipes: %s", strerror(errno)); + lua_pushfstring(L, "Error creating pipes: %s", strerror(errno)); + retval = -1; goto cleanup; } } self->pid = (long)fork(); if (self->pid < 0) { - retval = luaL_error(L, "Error running fork: %s.", strerror(errno)); + lua_pushfstring(L, "Error running fork: %s.", strerror(errno)); + retval = -1; goto cleanup; } else if (!self->pid) { if (!detach) @@ -333,6 +336,9 @@ static int process_start(lua_State* L) { close_fd(pipe); } } + if (retval == -1) + return lua_error(L); + self->running = true; return retval; } From 19845732141b58ed39f08b100f9015f6d712663d Mon Sep 17 00:00:00 2001 From: sammyette Date: Fri, 6 Jan 2023 15:27:05 -0400 Subject: [PATCH 013/148] fix: center title and version in emptyview (#1311) * fix: divide by amount of lines --- data/core/emptyview.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/core/emptyview.lua b/data/core/emptyview.lua index 0d0a929e..2152da3b 100644 --- a/data/core/emptyview.lua +++ b/data/core/emptyview.lua @@ -7,9 +7,15 @@ local View = require "core.view" local EmptyView = View:extend() local function draw_text(x, y, color) + local lines = { + { fmt = "%s to run a command", cmd = "core:find-command" }, + { fmt = "%s to open a file from the project", cmd = "core:find-file" }, + { fmt = "%s to change project folder", cmd = "core:change-project-folder" }, + { fmt = "%s to open a project folder", cmd = "core:open-project-folder" }, + } local th = style.big_font:get_height() local dh = 2 * th + style.padding.y * 2 - local x1, y1 = x, y + (dh - th) / 2 + local x1, y1 = x, y + ((dh - th) / #lines) local xv = x1 local title = "Lite XL" local version = "version " .. VERSION @@ -24,12 +30,6 @@ local function draw_text(x, y, color) renderer.draw_text(style.font, version, xv, y1 + th, color) x = x + style.padding.x renderer.draw_rect(x, y, math.ceil(1 * SCALE), dh, color) - local lines = { - { fmt = "%s to run a command", cmd = "core:find-command" }, - { fmt = "%s to open a file from the project", cmd = "core:find-file" }, - { fmt = "%s to change project folder", cmd = "core:change-project-folder" }, - { fmt = "%s to open a project folder", cmd = "core:open-project-folder" }, - } th = style.font:get_height() y = y + (dh - (th + style.padding.y) * #lines) / 2 local w = 0 From 291e7eab6fd515f92e79d48a49dad6c3c2653367 Mon Sep 17 00:00:00 2001 From: jgmdev Date: Sun, 8 Jan 2023 02:32:31 -0400 Subject: [PATCH 014/148] packaging: use master branch for plugin addons --- scripts/common.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/common.sh b/scripts/common.sh index 58fbd312..7078c99c 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -32,12 +32,12 @@ addons_download() { # Downlaod thirdparty plugins curl --insecure \ - -L "https://github.com/lite-xl/lite-xl-plugins/archive/2.1.zip" \ + -L "https://github.com/lite-xl/lite-xl-plugins/archive/master.zip" \ -o "${build_dir}/lite-xl-plugins.zip" unzip "${build_dir}/lite-xl-plugins.zip" -d "${build_dir}" - mv "${build_dir}/lite-xl-plugins-2.1/plugins" "${build_dir}/third/data" - rm -rf "${build_dir}/lite-xl-plugins-2.1" + mv "${build_dir}/lite-xl-plugins-master/plugins" "${build_dir}/third/data" + rm -rf "${build_dir}/lite-xl-plugins-master" } # Addons installation: some distributions forbid external downloads From 2d0ddc302f6dc2d852f5d160247f8d85239f2335 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Tue, 10 Jan 2023 05:50:26 +0800 Subject: [PATCH 015/148] Reorganize resources/ + wasm target (#1244) * add README.md to resources directory * add cross/ directory for meson cross files * fix readme list syntax error * fix reflink * disable ASYNCIFY_ADVISE by default * use executable names instead of hardcoding paths --- resources/README.md | 23 ++++++++++ .../macos_arm64.txt} | 3 ++ resources/cross/wasm.txt | 46 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 resources/README.md rename resources/{macos/macos_arm64.conf => cross/macos_arm64.txt} (78%) create mode 100644 resources/cross/wasm.txt diff --git a/resources/README.md b/resources/README.md new file mode 100644 index 00000000..975881c4 --- /dev/null +++ b/resources/README.md @@ -0,0 +1,23 @@ +# Resources + +This folder contains resources that is used for building or packaging the project. + +### Build + +- `cross/*.txt`: Meson [cross files][1] for cross-compiling lite-xl on other platforms. + +### Packaging + +- `icons/icon.{icns,ico,inl,rc,svg}`: lite-xl icon in various formats. +- `linux/org.lite_xl.lite_xl.appdata.xml`: AppStream metadata. +- `linux/org.lite_xl.lite_xl.desktop`: Desktop file for Linux desktops. +- `macos/appdmg.png`: Background image for packaging MacOS DMGs. +- `macos/Info.plist.in`: Template for generating `info.plist` on MacOS. See `macos/macos-retina-display.md` for details. +- `windows/001-lua-unicode.diff`: Patch for allowing Lua to load files with UTF-8 filenames on Windows. + +### Development + +- `lite_xl_plugin_api.h`: Native plugin API header. See the contents of `lite_xl_plugin_api.h` for more details. + + +[1]: https://mesonbuild.com/Cross-compilation.html \ No newline at end of file diff --git a/resources/macos/macos_arm64.conf b/resources/cross/macos_arm64.txt similarity index 78% rename from resources/macos/macos_arm64.conf rename to resources/cross/macos_arm64.txt index b1371b3b..3ccc6aa5 100644 --- a/resources/macos/macos_arm64.conf +++ b/resources/cross/macos_arm64.txt @@ -1,3 +1,6 @@ +# cross file for compiling on MacOS ARM (Apple Sillicon). +# use this file by running meson setup --cross-file resources/cross/macos_arm64.txt + [host_machine] system = 'darwin' cpu_family = 'aarch64' diff --git a/resources/cross/wasm.txt b/resources/cross/wasm.txt new file mode 100644 index 00000000..a6e87a06 --- /dev/null +++ b/resources/cross/wasm.txt @@ -0,0 +1,46 @@ +# cross file for WASM. +# use this file by running meson setup --cross-file resources/cross/wasm.txt + +[constants] + +# a list of functions that can run without being asyncified; proceed with caution +asyncify_ignores = '["SDL_BlitScaled","SDL_UpperBlitScaled","SDL_MapRGB*","SDL_FillRect","SDL_FreeSurface","SDL_CreateRGBSurface","SDL_GetWindowSurface","SDL_PollEvent","SDL_CreateSystemCursor","SDL_SetWindowTitle","SDL_SetCursor","SDL_GetWindowSize","SDL_GetWindowPosition","lua_push*","lua_rawget*","luaL_check*","pcre2*","FT_*","Bezier_*","g_*","FT_*","ft_*","TT_*","tt_*","__*","*printf","gray_*","fopen","fclose","fread","fflush","qsort","sift"]' + +# enable advising for optimizing the list above; disable this to prevent flooding logs +asyncify_advise = '0' + +# initial heap size in bytes; make sure it is not too low (around 64mb - 250mb) +initial_heap = '104857600' + + +[binaries] +c = 'emcc' +cpp = 'em++' +ar = 'emar' +strip = 'emstrip' +cmake = ['emmake', 'cmake'] +pkg-config = ['emconfigure', 'pkg-config'] +sdl2-config = ['emconfigure', 'sdl2-config'] + + +[properties] +needs_exe_wrapper = true + + +[built-in options] +c_args = [] +c_link_args = [] +cpp_args = [] +cpp_link_args = [] + + +[project options] +buildtype = 'release' +c_link_args = ['-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'INITIAL_MEMORY=' + initial_heap, '-s', 'ASYNCIFY=1', '-s', 'ASYNCIFY_ADVISE=' + asyncify_advise, '-s', 'ASYNCIFY_STACK_SIZE=6144', '-s', 'ASYNCIFY_REMOVE=' + asyncify_ignores, '-s', 'FORCE_FILESYSTEM=1'] + + +[host_machine] +system = 'emscripten' +cpu_family = 'wasm32' +cpu = 'wasm32' +endian = 'little' From c8afe3d1bf2638240d336cb34b10cbd163af3463 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 12 Jan 2023 00:25:06 +0100 Subject: [PATCH 016/148] replace uses of SDL_Window with RenWindow (#1319) Since Renwindow contains our instance of SDL_Window we can use this to simplify future logic to create separate window instances --- src/api/system.c | 46 +++++++++++++++++++++++----------------------- src/main.c | 2 +- src/renderer.c | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/api/system.c b/src/api/system.c index 5e55acce..36d9c680 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -7,6 +7,7 @@ #include #include "api.h" #include "../rencache.h" +#include "../renwindow.h" #ifdef _WIN32 #include #include @@ -36,8 +37,7 @@ #endif #endif -extern SDL_Window *window; - +extern RenWindow window_renderer; static const char* button_name(int button) { switch (button) { @@ -76,7 +76,7 @@ static SDL_HitTestResult SDLCALL hit_test(SDL_Window *window, const SDL_Point *p const int controls_width = hit_info->controls_width; int w, h; - SDL_GetWindowSize(window, &w, &h); + SDL_GetWindowSize(window_renderer.window, &w, &h); if (pt->y < hit_info->title_height && #if RESIZE_FROM_TOP @@ -326,7 +326,7 @@ top: return 3; case SDL_FINGERDOWN: - SDL_GetWindowSize(window, &w, &h); + SDL_GetWindowSize(window_renderer.window, &w, &h); lua_pushstring(L, "touchpressed"); lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w)); @@ -335,7 +335,7 @@ top: return 4; case SDL_FINGERUP: - SDL_GetWindowSize(window, &w, &h); + SDL_GetWindowSize(window_renderer.window, &w, &h); lua_pushstring(L, "touchreleased"); lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w)); @@ -351,7 +351,7 @@ top: e.tfinger.dx += event_plus.tfinger.dx; e.tfinger.dy += event_plus.tfinger.dy; } - SDL_GetWindowSize(window, &w, &h); + SDL_GetWindowSize(window_renderer.window, &w, &h); lua_pushstring(L, "touchmoved"); lua_pushinteger(L, (lua_Integer)(e.tfinger.x * w)); @@ -415,7 +415,7 @@ static int f_set_cursor(lua_State *L) { static int f_set_window_title(lua_State *L) { const char *title = luaL_checkstring(L, 1); - SDL_SetWindowTitle(window, title); + SDL_SetWindowTitle(window_renderer.window, title); return 0; } @@ -425,39 +425,39 @@ enum { WIN_NORMAL, WIN_MINIMIZED, WIN_MAXIMIZED, WIN_FULLSCREEN }; static int f_set_window_mode(lua_State *L) { int n = luaL_checkoption(L, 1, "normal", window_opts); - SDL_SetWindowFullscreen(window, + SDL_SetWindowFullscreen(window_renderer.window, n == WIN_FULLSCREEN ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - if (n == WIN_NORMAL) { SDL_RestoreWindow(window); } - if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(window); } - if (n == WIN_MINIMIZED) { SDL_MinimizeWindow(window); } + if (n == WIN_NORMAL) { SDL_RestoreWindow(window_renderer.window); } + if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(window_renderer.window); } + if (n == WIN_MINIMIZED) { SDL_MinimizeWindow(window_renderer.window); } return 0; } static int f_set_window_bordered(lua_State *L) { int bordered = lua_toboolean(L, 1); - SDL_SetWindowBordered(window, bordered); + SDL_SetWindowBordered(window_renderer.window, bordered); return 0; } static int f_set_window_hit_test(lua_State *L) { if (lua_gettop(L) == 0) { - SDL_SetWindowHitTest(window, NULL, NULL); + SDL_SetWindowHitTest(window_renderer.window, NULL, NULL); return 0; } window_hit_info->title_height = luaL_checknumber(L, 1); window_hit_info->controls_width = luaL_checknumber(L, 2); window_hit_info->resize_border = luaL_checknumber(L, 3); - SDL_SetWindowHitTest(window, hit_test, window_hit_info); + SDL_SetWindowHitTest(window_renderer.window, hit_test, window_hit_info); return 0; } static int f_get_window_size(lua_State *L) { int x, y, w, h; - SDL_GetWindowSize(window, &w, &h); - SDL_GetWindowPosition(window, &x, &y); + SDL_GetWindowSize(window_renderer.window, &w, &h); + SDL_GetWindowPosition(window_renderer.window, &x, &y); lua_pushinteger(L, w); lua_pushinteger(L, h); lua_pushinteger(L, x); @@ -471,22 +471,22 @@ static int f_set_window_size(lua_State *L) { double h = luaL_checknumber(L, 2); double x = luaL_checknumber(L, 3); double y = luaL_checknumber(L, 4); - SDL_SetWindowSize(window, w, h); - SDL_SetWindowPosition(window, x, y); + SDL_SetWindowSize(window_renderer.window, w, h); + SDL_SetWindowPosition(window_renderer.window, x, y); ren_resize_window(); return 0; } static int f_window_has_focus(lua_State *L) { - unsigned flags = SDL_GetWindowFlags(window); + unsigned flags = SDL_GetWindowFlags(window_renderer.window); lua_pushboolean(L, flags & SDL_WINDOW_INPUT_FOCUS); return 1; } static int f_get_window_mode(lua_State *L) { - unsigned flags = SDL_GetWindowFlags(window); + unsigned flags = SDL_GetWindowFlags(window_renderer.window); if (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) { lua_pushstring(L, "fullscreen"); } else if (flags & SDL_WINDOW_MINIMIZED) { @@ -524,8 +524,8 @@ static int f_raise_window(lua_State *L) { to allow the window to be focused. Also on wayland the raise window event may not always be obeyed. */ - SDL_SetWindowInputFocus(window); - SDL_RaiseWindow(window); + SDL_SetWindowInputFocus(window_renderer.window); + SDL_RaiseWindow(window_renderer.window); return 0; } @@ -901,7 +901,7 @@ static int f_fuzzy_match(lua_State *L) { static int f_set_window_opacity(lua_State *L) { double n = luaL_checknumber(L, 1); - int r = SDL_SetWindowOpacity(window, n); + int r = SDL_SetWindowOpacity(window_renderer.window, n); lua_pushboolean(L, r > -1); return 1; } diff --git a/src/main.c b/src/main.c index 19b7d40f..3c08a643 100644 --- a/src/main.c +++ b/src/main.c @@ -18,7 +18,7 @@ #endif -SDL_Window *window; +static SDL_Window *window; static double get_scale(void) { #ifndef __APPLE__ diff --git a/src/renderer.c b/src/renderer.c index 4319f042..2932784a 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -20,7 +20,7 @@ #define MAX_LOADABLE_GLYPHSETS 1024 #define SUBPIXEL_BITMAPS_CACHED 3 -static RenWindow window_renderer = {0}; +RenWindow window_renderer = {0}; static FT_Library library; // draw_rect_surface is used as a 1x1 surface to simplify ren_draw_rect with blending From ae218bc0056418c5333083af5a24e6bafc6f9742 Mon Sep 17 00:00:00 2001 From: adityaraj <75035219+pegvin@users.noreply.github.com> Date: Thu, 12 Jan 2023 05:23:23 +0530 Subject: [PATCH 017/148] Create Renderer Only When It Doesn't Exist (#1315) --- src/renwindow.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/renwindow.c b/src/renwindow.c index 9356ed21..85fd7a07 100644 --- a/src/renwindow.c +++ b/src/renwindow.c @@ -17,11 +17,12 @@ static int query_surface_scale(RenWindow *ren) { static void setup_renderer(RenWindow *ren, int w, int h) { /* Note that w and h here should always be in pixels and obtained from a call to SDL_GL_GetDrawableSize(). */ - if (ren->renderer) { - SDL_DestroyTexture(ren->texture); - SDL_DestroyRenderer(ren->renderer); + if (!ren->renderer) { + ren->renderer = SDL_CreateRenderer(ren->window, -1, 0); + } + if (ren->texture) { + SDL_DestroyTexture(ren->texture); } - ren->renderer = SDL_CreateRenderer(ren->window, -1, 0); ren->texture = SDL_CreateTexture(ren->renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STREAMING, w, h); ren->surface_scale = query_surface_scale(ren); } From 38fa9f976c2d920c2fb1e11d5be5d702f7198217 Mon Sep 17 00:00:00 2001 From: xwii Date: Sat, 14 Jan 2023 01:33:13 +0700 Subject: [PATCH 018/148] Use `table.move` to implement `common.splice` (#1324) * Use `table.move` to implement `common.splice` * Disallow negative `remove` in `common.splice` --- data/core/common.lua | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/data/core/common.lua b/data/core/common.lua index a4ea01f5..b6c9db67 100644 --- a/data/core/common.lua +++ b/data/core/common.lua @@ -82,25 +82,14 @@ end function common.splice(t, at, remove, insert) + assert(remove >= 0, "bad argument #3 to 'splice' (non-negative value expected)") insert = insert or {} - local offset = #insert - remove - local old_len = #t - if offset < 0 then - for i = at - offset, old_len - offset do - t[i + offset] = t[i] - end - elseif offset > 0 then - for i = old_len, at, -1 do - t[i + offset] = t[i] - end - end - for i, item in ipairs(insert) do - t[at + i - 1] = item - end + local len = #insert + if remove ~= len then table.move(t, at + remove, #t + remove, at + len) end + table.move(insert, 1, len, at, t) end - local function compare_score(a, b) return a.score > b.score end From a9d8f12cb79dd710b19db1f66f97b061bc8b5837 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 13 Jan 2023 19:34:09 +0100 Subject: [PATCH 019/148] Make empty groups in `regex.gmatch` return their offset (#1325) This makes `regex.gmatch` behave like `string.gmatch`. --- src/api/regex.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/api/regex.c b/src/api/regex.c index f86e7ff6..bf17d424 100644 --- a/src/api/regex.c +++ b/src/api/regex.c @@ -91,7 +91,10 @@ static int regex_gmatch_iterator(lua_State *L) { int total_results = ovector_count * 2; size_t last_offset = 0; for (int i = index; i < total_results; i+=2) { - lua_pushlstring(L, state->subject+ovector[i], ovector[i+1] - ovector[i]); + if (ovector[i] == ovector[i+1]) + lua_pushinteger(L, ovector[i] + 1); + else + lua_pushlstring(L, state->subject+ovector[i], ovector[i+1] - ovector[i]); last_offset = ovector[i+1]; total++; } From 4c18cf6744cc8f26d7af7634e4d029f23f973d24 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Fri, 13 Jan 2023 16:31:28 -0500 Subject: [PATCH 020/148] Updated dummy method signature to match prototypes. --- src/api/dirmonitor/dummy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/dirmonitor/dummy.c b/src/api/dirmonitor/dummy.c index 47aa0990..0690f61d 100644 --- a/src/api/dirmonitor/dummy.c +++ b/src/api/dirmonitor/dummy.c @@ -2,7 +2,7 @@ struct dirmonitor_internal* init_dirmonitor() { return NULL; } void deinit_dirmonitor(struct dirmonitor_internal* monitor) { } -int get_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, size_t len) { return -1; } +int get_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int len) { return -1; } int translate_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int size, int (*callback)(int, const char*, void*), void* data) { return -1; } int add_dirmonitor(struct dirmonitor_internal* monitor, const char* path) { return -1; } void remove_dirmonitor(struct dirmonitor_internal* monitor, int fd) { } From d54a5d0672f217a81d423910c49e3abc3015f937 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 19 Jan 2023 02:43:48 +0100 Subject: [PATCH 021/148] remove static libgcc from meson (#1290) --- meson.build | 4 ---- 1 file changed, 4 deletions(-) diff --git a/meson.build b/meson.build index e5fc1fbe..7bbecc68 100644 --- a/meson.build +++ b/meson.build @@ -63,10 +63,6 @@ lite_cargs += '-DLITE_ARCH_TUPLE="@0@"'.format(arch_tuple) # Linker Settings #=============================================================================== lite_link_args = [] -if cc.get_id() == 'gcc' and get_option('buildtype') == 'release' - lite_link_args += ['-static-libgcc'] -endif - if host_machine.system() == 'darwin' lite_link_args += ['-framework', 'CoreServices', '-framework', 'Foundation'] endif From bddb5e274da5a4b9ec7e418ed4f7a6e45c11edba Mon Sep 17 00:00:00 2001 From: Guldoman Date: Thu, 19 Jan 2023 04:15:26 +0100 Subject: [PATCH 022/148] Avoid drawing hidden text in `DocView:draw_line_text` (#1298) * Stop drawing text past the `DocView` edge in `DocView:draw_line_text` * Don't add draw commands if they fall outside the latest clip The check was previously done with the window rect, so this will reduce a bit more the number of commands sent. --- data/core/docview.lua | 1 + src/rencache.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/data/core/docview.lua b/data/core/docview.lua index 6b7913c8..bf222738 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -422,6 +422,7 @@ function DocView:draw_line_text(line, x, y) -- do not render newline, fixes issue #1164 if tidx == last_token then text = text:sub(1, -2) end tx = renderer.draw_text(font, text, tx, ty, color) + if tx > self.position.x + self.size.x then break end end return self:get_line_height() end diff --git a/src/rencache.c b/src/rencache.c index 12c2a33c..f0243f0b 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -54,6 +54,7 @@ uint8_t *command_buf = NULL; static bool resize_issue; static int command_buf_idx; static RenRect screen_rect; +static RenRect last_clip_rect; static bool show_debug; static inline int rencache_min(int a, int b) { return a < b ? a : b; } @@ -156,12 +157,15 @@ void rencache_show_debug(bool enable) { void rencache_set_clip_rect(RenRect rect) { Command *cmd = push_command(SET_CLIP, COMMAND_BARE_SIZE); - if (cmd) { cmd->rect = intersect_rects(rect, screen_rect); } + if (cmd) { + cmd->rect = intersect_rects(rect, screen_rect); + last_clip_rect = cmd->rect; + } } void rencache_draw_rect(RenRect rect, RenColor color) { - if (!rects_overlap(screen_rect, rect) || rect.width == 0 || rect.height == 0) { + if (rect.width == 0 || rect.height == 0 || !rects_overlap(last_clip_rect, rect)) { return; } Command *cmd = push_command(DRAW_RECT, COMMAND_BARE_SIZE); @@ -175,7 +179,7 @@ float rencache_draw_text(RenFont **fonts, const char *text, size_t len, float x, { float width = ren_font_group_get_width(fonts, text, len); RenRect rect = { x, y, (int)width, ren_font_group_get_height(fonts) }; - if (rects_overlap(screen_rect, rect)) { + if (rects_overlap(last_clip_rect, rect)) { int sz = len + 1; Command *cmd = push_command(DRAW_TEXT, COMMAND_BARE_SIZE + sz); if (cmd) { @@ -207,6 +211,7 @@ void rencache_begin_frame() { screen_rect.height = h; rencache_invalidate(); } + last_clip_rect = screen_rect; } From 95f18a11488e8885b2acd24d924393c20aff5418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jefferson=20Gonz=C3=A1lez?= Date: Thu, 19 Jan 2023 20:27:23 -0400 Subject: [PATCH 023/148] plugin api: allow usage on multiple source files (#1335) As discussed with Adam on discord current Lite XL Lua Plugin API was not working on native plugins with more than 1 source file since imported symbols were not exposed to other unit files. The issue was tackled on #1332 but the solution introduced another issue when Lite XL was dynamically linked to the system lua. So we opted to tackle this by using function wrappers around the function pointers. --- resources/lite_xl_plugin_api.h | 1179 ++++++++++++++++++++------------ 1 file changed, 758 insertions(+), 421 deletions(-) diff --git a/resources/lite_xl_plugin_api.h b/resources/lite_xl_plugin_api.h index 5337d8ae..257791ce 100644 --- a/resources/lite_xl_plugin_api.h +++ b/resources/lite_xl_plugin_api.h @@ -3,12 +3,18 @@ /** The lite_xl plugin API is quite simple. Any shared library can be a plugin file, so long as it has an entrypoint that looks like the following, where xxxxx is the plugin name: + +#define LITE_XL_PLUGIN_ENTRYPOINT #include "lite_xl_plugin_api.h" int luaopen_lite_xl_xxxxx(lua_State* L, void* XL) { lite_xl_plugin_init(XL); ... return 1; } + +NOTE: `#define LITE_XL_PLUGIN_ENTRYPOINT` needs to be defined only on the +source file where the lite_xl_plugin_init() initialization function is called. + In linux, to compile this file, you'd do: 'gcc -o xxxxx.so -shared xxxxx.c'. Simple! Due to the way the API is structured, you *should not* link or include lua libraries. This file was automatically generated. DO NOT MODIFY DIRECTLY. @@ -23,6 +29,28 @@ Go figure. #include #include // for BUFSIZ? this is kinda weird +#define SYMBOL_WRAP_DECL(ret, name, ...) \ + ret name(__VA_ARGS__) + +#define SYMBOL_WRAP_CALL(name, ...) \ + return __##name(__VA_ARGS__) + +#define SYMBOL_WRAP_CALL_FB(name, ...) \ + return __lite_xl_fallback_##name(__VA_ARGS__) + +#ifdef LITE_XL_PLUGIN_ENTRYPOINT + #define SYMBOL_DECLARE(ret, name, ...) \ + static ret (*__##name) (__VA_ARGS__); \ + SYMBOL_WRAP_DECL(ret, name, __VA_ARGS__); \ + static ret __lite_xl_fallback_##name(__VA_ARGS__) { \ + fputs("warning: " #name " is a stub", stderr); \ + exit(1); \ + } +#else + #define SYMBOL_DECLARE(ret, name, ...) \ + SYMBOL_WRAP_DECL(ret, name, __VA_ARGS__); +#endif + /** luaconf.h **/ #ifndef lconfig_h @@ -227,101 +255,103 @@ struct lua_Debug { char short_src[LUA_IDSIZE]; struct CallInfo *i_ci; }; -static lua_State *(*lua_newstate) (lua_Alloc f, void *ud); -static void (*lua_close) (lua_State *L); -static lua_State *(*lua_newthread) (lua_State *L); -static lua_CFunction (*lua_atpanic) (lua_State *L, lua_CFunction panicf); -static const lua_Number *(*lua_version) (lua_State *L); -static int (*lua_absindex) (lua_State *L, int idx); -static int (*lua_gettop) (lua_State *L); -static void (*lua_settop) (lua_State *L, int idx); -static void (*lua_pushvalue) (lua_State *L, int idx); -static void (*lua_copy) (lua_State *L, int fromidx, int toidx); -static int (*lua_checkstack) (lua_State *L, int sz); -static void (*lua_xmove) (lua_State *from, lua_State *to, int n); -static int (*lua_isnumber) (lua_State *L, int idx); -static int (*lua_isstring) (lua_State *L, int idx); -static int (*lua_iscfunction) (lua_State *L, int idx); -static int (*lua_isuserdata) (lua_State *L, int idx); -static int (*lua_type) (lua_State *L, int idx); -static const char *(*lua_typename) (lua_State *L, int tp); -static lua_Number (*lua_tonumberx) (lua_State *L, int idx, int *isnum); -static lua_Integer (*lua_tointegerx) (lua_State *L, int idx, int *isnum); -static lua_Unsigned (*lua_tounsignedx) (lua_State *L, int idx, int *isnum); -static int (*lua_toboolean) (lua_State *L, int idx); -static const char *(*lua_tolstring) (lua_State *L, int idx, size_t *len); -static size_t (*lua_rawlen) (lua_State *L, int idx); -static lua_CFunction (*lua_tocfunction) (lua_State *L, int idx); -static void *(*lua_touserdata) (lua_State *L, int idx); -static lua_State *(*lua_tothread) (lua_State *L, int idx); -static const void *(*lua_topointer) (lua_State *L, int idx); -static void (*lua_arith) (lua_State *L, int op); -static int (*lua_rawequal) (lua_State *L, int idx1, int idx2); -static int (*lua_compare) (lua_State *L, int idx1, int idx2, int op); -static void (*lua_pushnil) (lua_State *L); -static void (*lua_pushnumber) (lua_State *L, lua_Number n); -static void (*lua_pushinteger) (lua_State *L, lua_Integer n); -static void (*lua_pushunsigned) (lua_State *L, lua_Unsigned n); -static const char *(*lua_pushlstring) (lua_State *L, const char *s, size_t l); -static const char *(*lua_pushstring) (lua_State *L, const char *s); -static const char *(*lua_pushvfstring) (lua_State *L, const char *fmt, va_list argp); -static const char *(*lua_pushfstring) (lua_State *L, const char *fmt, ...); -static void (*lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); -static void (*lua_pushboolean) (lua_State *L, int b); -static void (*lua_pushlightuserdata) (lua_State *L, void *p); -static int (*lua_pushthread) (lua_State *L); -static void (*lua_getglobal) (lua_State *L, const char *var); -static void (*lua_gettable) (lua_State *L, int idx); -static void (*lua_getfield) (lua_State *L, int idx, const char *k); -static void (*lua_rawget) (lua_State *L, int idx); -static void (*lua_rawgeti) (lua_State *L, int idx, int n); -static void (*lua_rawgetp) (lua_State *L, int idx, const void *p); -static void (*lua_createtable) (lua_State *L, int narr, int nrec); -static void *(*lua_newuserdata) (lua_State *L, size_t sz); -static void *(*lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue); -static int (*lua_getmetatable) (lua_State *L, int objindex); -static void (*lua_getuservalue) (lua_State *L, int idx); -static void (*lua_getiuservalue) (lua_State *L, int idx, int n); -static void (*lua_setglobal) (lua_State *L, const char *var); -static void (*lua_settable) (lua_State *L, int idx); -static void (*lua_setfield) (lua_State *L, int idx, const char *k); -static void (*lua_rawset) (lua_State *L, int idx); -static void (*lua_rawseti) (lua_State *L, int idx, int n); -static void (*lua_rawsetp) (lua_State *L, int idx, const void *p); -static int (*lua_setmetatable) (lua_State *L, int objindex); -static void (*lua_setuservalue) (lua_State *L, int idx); -static void (*lua_setiuservalue) (lua_State *L, int idx, int n); -static void (*lua_callk) (lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k); -static int (*lua_getctx) (lua_State *L, int *ctx); -static int (*lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k); -static int (*lua_load) (lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); -static int (*lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); -static int (*lua_yieldk) (lua_State *L, int nresults, int ctx, lua_CFunction k); -static int (*lua_resume) (lua_State *L, lua_State *from, int narg); -static int (*lua_status) (lua_State *L); -static int (*lua_gc) (lua_State *L, int what, int data); -static int (*lua_error) (lua_State *L); -static int (*lua_next) (lua_State *L, int idx); -static void (*lua_concat) (lua_State *L, int n); -static void (*lua_len) (lua_State *L, int idx); -static lua_Alloc (*lua_getallocf) (lua_State *L, void **ud); -static void (*lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); -static int (*lua_getstack) (lua_State *L, int level, lua_Debug *ar); -static int (*lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); -static const char *(*lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); -static const char *(*lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); -static const char *(*lua_getupvalue) (lua_State *L, int funcindex, int n); -static const char *(*lua_setupvalue) (lua_State *L, int funcindex, int n); -static void *(*lua_upvalueid) (lua_State *L, int fidx, int n); -static void (*lua_upvaluejoin) (lua_State *L, int fidx1, int n1, int fidx2, int n2); -static int (*lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); -static lua_Hook (*lua_gethook) (lua_State *L); -static int (*lua_gethookmask) (lua_State *L); -static int (*lua_gethookcount) (lua_State *L); + +SYMBOL_DECLARE(lua_State *, lua_newstate, lua_Alloc f, void *ud) +SYMBOL_DECLARE(void, lua_close, lua_State *L) +SYMBOL_DECLARE(lua_State *, lua_newthread, lua_State *L) +SYMBOL_DECLARE(lua_CFunction, lua_atpanic, lua_State *L, lua_CFunction panicf) +SYMBOL_DECLARE(const lua_Number *, lua_version, lua_State *L) +SYMBOL_DECLARE(int, lua_absindex, lua_State *L, int idx) +SYMBOL_DECLARE(int, lua_gettop, lua_State *L) +SYMBOL_DECLARE(void, lua_settop, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_pushvalue, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_copy, lua_State *L, int fromidx, int toidx) +SYMBOL_DECLARE(int, lua_checkstack, lua_State *L, int sz) +SYMBOL_DECLARE(void, lua_xmove, lua_State *from, lua_State *to, int n) +SYMBOL_DECLARE(int, lua_isnumber, lua_State *L, int idx) +SYMBOL_DECLARE(int, lua_isstring, lua_State *L, int idx) +SYMBOL_DECLARE(int, lua_iscfunction, lua_State *L, int idx) +SYMBOL_DECLARE(int, lua_isuserdata, lua_State *L, int idx) +SYMBOL_DECLARE(int, lua_type, lua_State *L, int idx) +SYMBOL_DECLARE(const char *, lua_typename, lua_State *L, int tp) +SYMBOL_DECLARE(lua_Number, lua_tonumberx, lua_State *L, int idx, int *isnum) +SYMBOL_DECLARE(lua_Integer, lua_tointegerx, lua_State *L, int idx, int *isnum) +SYMBOL_DECLARE(lua_Unsigned, lua_tounsignedx, lua_State *L, int idx, int *isnum) +SYMBOL_DECLARE(int, lua_toboolean, lua_State *L, int idx) +SYMBOL_DECLARE(const char *, lua_tolstring, lua_State *L, int idx, size_t *len) +SYMBOL_DECLARE(size_t, lua_rawlen, lua_State *L, int idx) +SYMBOL_DECLARE(lua_CFunction, lua_tocfunction, lua_State *L, int idx) +SYMBOL_DECLARE(void *, lua_touserdata, lua_State *L, int idx) +SYMBOL_DECLARE(lua_State *, lua_tothread, lua_State *L, int idx) +SYMBOL_DECLARE(const void *, lua_topointer, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_arith, lua_State *L, int op) +SYMBOL_DECLARE(int, lua_rawequal, lua_State *L, int idx1, int idx2) +SYMBOL_DECLARE(int, lua_compare, lua_State *L, int idx1, int idx2, int op) +SYMBOL_DECLARE(void, lua_pushnil, lua_State *L) +SYMBOL_DECLARE(void, lua_pushnumber, lua_State *L, lua_Number n) +SYMBOL_DECLARE(void, lua_pushinteger, lua_State *L, lua_Integer n) +SYMBOL_DECLARE(void, lua_pushunsigned, lua_State *L, lua_Unsigned n) +SYMBOL_DECLARE(const char *, lua_pushlstring, lua_State *L, const char *s, size_t l) +SYMBOL_DECLARE(const char *, lua_pushstring, lua_State *L, const char *s) +SYMBOL_DECLARE(const char *, lua_pushvfstring, lua_State *L, const char *fmt, va_list argp) +SYMBOL_DECLARE(const char *, lua_pushfstring, lua_State *L, const char *fmt, ...) +SYMBOL_DECLARE(void, lua_pushcclosure, lua_State *L, lua_CFunction fn, int n) +SYMBOL_DECLARE(void, lua_pushboolean, lua_State *L, int b) +SYMBOL_DECLARE(void, lua_pushlightuserdata, lua_State *L, void *p) +SYMBOL_DECLARE(int, lua_pushthread, lua_State *L) +SYMBOL_DECLARE(void, lua_getglobal, lua_State *L, const char *var) +SYMBOL_DECLARE(void, lua_gettable, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_getfield, lua_State *L, int idx, const char *k) +SYMBOL_DECLARE(void, lua_rawget, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_rawgeti, lua_State *L, int idx, int n) +SYMBOL_DECLARE(void, lua_rawgetp, lua_State *L, int idx, const void *p) +SYMBOL_DECLARE(void, lua_createtable, lua_State *L, int narr, int nrec) +SYMBOL_DECLARE(void *, lua_newuserdata, lua_State *L, size_t sz) +SYMBOL_DECLARE(void *, lua_newuserdatauv, lua_State *L, size_t sz, int nuvalue) +SYMBOL_DECLARE(int, lua_getmetatable, lua_State *L, int objindex) +SYMBOL_DECLARE(void, lua_getuservalue, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_getiuservalue, lua_State *L, int idx, int n) +SYMBOL_DECLARE(void, lua_setglobal, lua_State *L, const char *var) +SYMBOL_DECLARE(void, lua_settable, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_setfield, lua_State *L, int idx, const char *k) +SYMBOL_DECLARE(void, lua_rawset, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_rawseti, lua_State *L, int idx, int n) +SYMBOL_DECLARE(void, lua_rawsetp, lua_State *L, int idx, const void *p) +SYMBOL_DECLARE(int, lua_setmetatable, lua_State *L, int objindex) +SYMBOL_DECLARE(void, lua_setuservalue, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_setiuservalue, lua_State *L, int idx, int n) +SYMBOL_DECLARE(void, lua_callk, lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k) +SYMBOL_DECLARE(int, lua_getctx, lua_State *L, int *ctx) +SYMBOL_DECLARE(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k) +SYMBOL_DECLARE(int, lua_load, lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode) +SYMBOL_DECLARE(int, lua_dump, lua_State *L, lua_Writer writer, void *data, int strip) +SYMBOL_DECLARE(int, lua_yieldk, lua_State *L, int nresults, int ctx, lua_CFunction k) +SYMBOL_DECLARE(int, lua_resume, lua_State *L, lua_State *from, int narg) +SYMBOL_DECLARE(int, lua_status, lua_State *L) +SYMBOL_DECLARE(int, lua_gc, lua_State *L, int what, int data) +SYMBOL_DECLARE(int, lua_error, lua_State *L) +SYMBOL_DECLARE(int, lua_next, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_concat, lua_State *L, int n) +SYMBOL_DECLARE(void, lua_len, lua_State *L, int idx) +SYMBOL_DECLARE(lua_Alloc, lua_getallocf, lua_State *L, void **ud) +SYMBOL_DECLARE(void, lua_setallocf, lua_State *L, lua_Alloc f, void *ud) +SYMBOL_DECLARE(int, lua_getstack, lua_State *L, int level, lua_Debug *ar) +SYMBOL_DECLARE(int, lua_getinfo, lua_State *L, const char *what, lua_Debug *ar) +SYMBOL_DECLARE(const char *, lua_getlocal, lua_State *L, const lua_Debug *ar, int n) +SYMBOL_DECLARE(const char *, lua_setlocal, lua_State *L, const lua_Debug *ar, int n) +SYMBOL_DECLARE(const char *, lua_getupvalue, lua_State *L, int funcindex, int n) +SYMBOL_DECLARE(const char *, lua_setupvalue, lua_State *L, int funcindex, int n) +SYMBOL_DECLARE(void *, lua_upvalueid, lua_State *L, int fidx, int n) +SYMBOL_DECLARE(void, lua_upvaluejoin, lua_State *L, int fidx1, int n1, int fidx2, int n2) +SYMBOL_DECLARE(int, lua_sethook, lua_State *L, lua_Hook func, int mask, int count) +SYMBOL_DECLARE(lua_Hook, lua_gethook, lua_State *L) +SYMBOL_DECLARE(int, lua_gethookmask, lua_State *L) +SYMBOL_DECLARE(int, lua_gethookcount, lua_State *L) + #define lua_h #define LUA_VERSION_MAJOR "5" -#define LUA_VERSION_MINOR "2" -#define LUA_VERSION_NUM 502 +#define LUA_VERSION_MINOR "4" +#define LUA_VERSION_NUM 504 #define LUA_VERSION_RELEASE "4" #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE @@ -408,98 +438,6 @@ static int (*lua_gethookcount) (lua_State *L); #define LUA_MASKRET (1 << LUA_HOOKRET) #define LUA_MASKLINE (1 << LUA_HOOKLINE) #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) -static lua_State * __lite_xl_fallback_lua_newstate (lua_Alloc f, void *ud) { fputs("warning: lua_newstate is a stub", stderr); } -static void __lite_xl_fallback_lua_close (lua_State *L) { fputs("warning: lua_close is a stub", stderr); } -static lua_State * __lite_xl_fallback_lua_newthread (lua_State *L) { fputs("warning: lua_newthread is a stub", stderr); } -static lua_CFunction __lite_xl_fallback_lua_atpanic (lua_State *L, lua_CFunction panicf) { fputs("warning: lua_atpanic is a stub", stderr); } -static const lua_Number * __lite_xl_fallback_lua_version (lua_State *L) { fputs("warning: lua_version is a stub", stderr); } -static int __lite_xl_fallback_lua_absindex (lua_State *L, int idx) { fputs("warning: lua_absindex is a stub", stderr); } -static int __lite_xl_fallback_lua_gettop (lua_State *L) { fputs("warning: lua_gettop is a stub", stderr); } -static void __lite_xl_fallback_lua_settop (lua_State *L, int idx) { fputs("warning: lua_settop is a stub", stderr); } -static void __lite_xl_fallback_lua_pushvalue (lua_State *L, int idx) { fputs("warning: lua_pushvalue is a stub", stderr); } -static void __lite_xl_fallback_lua_copy (lua_State *L, int fromidx, int toidx) { fputs("warning: lua_copy is a stub", stderr); } -static int __lite_xl_fallback_lua_checkstack (lua_State *L, int sz) { fputs("warning: lua_checkstack is a stub", stderr); } -static void __lite_xl_fallback_lua_xmove (lua_State *from, lua_State *to, int n) { fputs("warning: lua_xmove is a stub", stderr); } -static int __lite_xl_fallback_lua_isnumber (lua_State *L, int idx) { fputs("warning: lua_isnumber is a stub", stderr); } -static int __lite_xl_fallback_lua_isstring (lua_State *L, int idx) { fputs("warning: lua_isstring is a stub", stderr); } -static int __lite_xl_fallback_lua_iscfunction (lua_State *L, int idx) { fputs("warning: lua_iscfunction is a stub", stderr); } -static int __lite_xl_fallback_lua_isuserdata (lua_State *L, int idx) { fputs("warning: lua_isuserdata is a stub", stderr); } -static int __lite_xl_fallback_lua_type (lua_State *L, int idx) { fputs("warning: lua_type is a stub", stderr); } -static const char * __lite_xl_fallback_lua_typename (lua_State *L, int tp) { fputs("warning: lua_typename is a stub", stderr); } -static lua_Number __lite_xl_fallback_lua_tonumberx (lua_State *L, int idx, int *isnum) { fputs("warning: lua_tonumberx is a stub", stderr); } -static lua_Integer __lite_xl_fallback_lua_tointegerx (lua_State *L, int idx, int *isnum) { fputs("warning: lua_tointegerx is a stub", stderr); } -static lua_Unsigned __lite_xl_fallback_lua_tounsignedx (lua_State *L, int idx, int *isnum) { fputs("warning: lua_tounsignedx is a stub", stderr); } -static int __lite_xl_fallback_lua_toboolean (lua_State *L, int idx) { fputs("warning: lua_toboolean is a stub", stderr); } -static const char * __lite_xl_fallback_lua_tolstring (lua_State *L, int idx, size_t *len) { fputs("warning: lua_tolstring is a stub", stderr); } -static size_t __lite_xl_fallback_lua_rawlen (lua_State *L, int idx) { fputs("warning: lua_rawlen is a stub", stderr); } -static lua_CFunction __lite_xl_fallback_lua_tocfunction (lua_State *L, int idx) { fputs("warning: lua_tocfunction is a stub", stderr); } -static void * __lite_xl_fallback_lua_touserdata (lua_State *L, int idx) { fputs("warning: lua_touserdata is a stub", stderr); } -static lua_State * __lite_xl_fallback_lua_tothread (lua_State *L, int idx) { fputs("warning: lua_tothread is a stub", stderr); } -static const void * __lite_xl_fallback_lua_topointer (lua_State *L, int idx) { fputs("warning: lua_topointer is a stub", stderr); } -static void __lite_xl_fallback_lua_arith (lua_State *L, int op) { fputs("warning: lua_arith is a stub", stderr); } -static int __lite_xl_fallback_lua_rawequal (lua_State *L, int idx1, int idx2) { fputs("warning: lua_rawequal is a stub", stderr); } -static int __lite_xl_fallback_lua_compare (lua_State *L, int idx1, int idx2, int op) { fputs("warning: lua_compare is a stub", stderr); } -static void __lite_xl_fallback_lua_pushnil (lua_State *L) { fputs("warning: lua_pushnil is a stub", stderr); } -static void __lite_xl_fallback_lua_pushnumber (lua_State *L, lua_Number n) { fputs("warning: lua_pushnumber is a stub", stderr); } -static void __lite_xl_fallback_lua_pushinteger (lua_State *L, lua_Integer n) { fputs("warning: lua_pushinteger is a stub", stderr); } -static void __lite_xl_fallback_lua_pushunsigned (lua_State *L, lua_Unsigned n) { fputs("warning: lua_pushunsigned is a stub", stderr); } -static const char * __lite_xl_fallback_lua_pushlstring (lua_State *L, const char *s, size_t l) { fputs("warning: lua_pushlstring is a stub", stderr); } -static const char * __lite_xl_fallback_lua_pushstring (lua_State *L, const char *s) { fputs("warning: lua_pushstring is a stub", stderr); } -static const char * __lite_xl_fallback_lua_pushvfstring (lua_State *L, const char *fmt, va_list argp) { fputs("warning: lua_pushvfstring is a stub", stderr); } -static const char * __lite_xl_fallback_lua_pushfstring (lua_State *L, const char *fmt, ...) { fputs("warning: lua_pushfstring is a stub", stderr); } -static void __lite_xl_fallback_lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { fputs("warning: lua_pushcclosure is a stub", stderr); } -static void __lite_xl_fallback_lua_pushboolean (lua_State *L, int b) { fputs("warning: lua_pushboolean is a stub", stderr); } -static void __lite_xl_fallback_lua_pushlightuserdata (lua_State *L, void *p) { fputs("warning: lua_pushlightuserdata is a stub", stderr); } -static int __lite_xl_fallback_lua_pushthread (lua_State *L) { fputs("warning: lua_pushthread is a stub", stderr); } -static void __lite_xl_fallback_lua_getglobal (lua_State *L, const char *var) { fputs("warning: lua_getglobal is a stub", stderr); } -static void __lite_xl_fallback_lua_gettable (lua_State *L, int idx) { fputs("warning: lua_gettable is a stub", stderr); } -static void __lite_xl_fallback_lua_getfield (lua_State *L, int idx, const char *k) { fputs("warning: lua_getfield is a stub", stderr); } -static void __lite_xl_fallback_lua_rawget (lua_State *L, int idx) { fputs("warning: lua_rawget is a stub", stderr); } -static void __lite_xl_fallback_lua_rawgeti (lua_State *L, int idx, int n) { fputs("warning: lua_rawgeti is a stub", stderr); } -static void __lite_xl_fallback_lua_rawgetp (lua_State *L, int idx, const void *p) { fputs("warning: lua_rawgetp is a stub", stderr); } -static void __lite_xl_fallback_lua_createtable (lua_State *L, int narr, int nrec) { fputs("warning: lua_createtable is a stub", stderr); } -static void * __lite_xl_fallback_lua_newuserdata (lua_State *L, size_t sz) { fputs("warning: lua_newuserdata is a stub", stderr); } -static void * __lite_xl_fallback_lua_newuserdatauv (lua_State *L, size_t sz, int nuvalue) { fputs("warning: lua_newuserdatauv is a stub", stderr); } -static int __lite_xl_fallback_lua_getmetatable (lua_State *L, int objindex) { fputs("warning: lua_getmetatable is a stub", stderr); } -static void __lite_xl_fallback_lua_getuservalue (lua_State *L, int idx) { fputs("warning: lua_getuservalue is a stub", stderr); } -static void __lite_xl_fallback_lua_getiuservalue (lua_State *L, int idx, int n) { fputs("warning: lua_getiuservalue is a stub", stderr); } -static void __lite_xl_fallback_lua_setglobal (lua_State *L, const char *var) { fputs("warning: lua_setglobal is a stub", stderr); } -static void __lite_xl_fallback_lua_settable (lua_State *L, int idx) { fputs("warning: lua_settable is a stub", stderr); } -static void __lite_xl_fallback_lua_setfield (lua_State *L, int idx, const char *k) { fputs("warning: lua_setfield is a stub", stderr); } -static void __lite_xl_fallback_lua_rawset (lua_State *L, int idx) { fputs("warning: lua_rawset is a stub", stderr); } -static void __lite_xl_fallback_lua_rawseti (lua_State *L, int idx, int n) { fputs("warning: lua_rawseti is a stub", stderr); } -static void __lite_xl_fallback_lua_rawsetp (lua_State *L, int idx, const void *p) { fputs("warning: lua_rawsetp is a stub", stderr); } -static int __lite_xl_fallback_lua_setmetatable (lua_State *L, int objindex) { fputs("warning: lua_setmetatable is a stub", stderr); } -static void __lite_xl_fallback_lua_setuservalue (lua_State *L, int idx) { fputs("warning: lua_setuservalue is a stub", stderr); } -static void __lite_xl_fallback_lua_setiuservalue (lua_State *L, int idx, int n) { fputs("warning: lua_setiuservalue is a stub", stderr); } -static void __lite_xl_fallback_lua_callk (lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k) { fputs("warning: lua_callk is a stub", stderr); } -static int __lite_xl_fallback_lua_getctx (lua_State *L, int *ctx) { fputs("warning: lua_getctx is a stub", stderr); } -static int __lite_xl_fallback_lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k) { fputs("warning: lua_pcallk is a stub", stderr); } -static int __lite_xl_fallback_lua_load (lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode) { fputs("warning: lua_load is a stub", stderr); } -static int __lite_xl_fallback_lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { fputs("warning: lua_dump is a stub", stderr); } -static int __lite_xl_fallback_lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) { fputs("warning: lua_yieldk is a stub", stderr); } -static int __lite_xl_fallback_lua_resume (lua_State *L, lua_State *from, int narg) { fputs("warning: lua_resume is a stub", stderr); } -static int __lite_xl_fallback_lua_status (lua_State *L) { fputs("warning: lua_status is a stub", stderr); } -static int __lite_xl_fallback_lua_gc (lua_State *L, int what, int data) { fputs("warning: lua_gc is a stub", stderr); } -static int __lite_xl_fallback_lua_error (lua_State *L) { fputs("warning: lua_error is a stub", stderr); } -static int __lite_xl_fallback_lua_next (lua_State *L, int idx) { fputs("warning: lua_next is a stub", stderr); } -static void __lite_xl_fallback_lua_concat (lua_State *L, int n) { fputs("warning: lua_concat is a stub", stderr); } -static void __lite_xl_fallback_lua_len (lua_State *L, int idx) { fputs("warning: lua_len is a stub", stderr); } -static lua_Alloc __lite_xl_fallback_lua_getallocf (lua_State *L, void **ud) { fputs("warning: lua_getallocf is a stub", stderr); } -static void __lite_xl_fallback_lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { fputs("warning: lua_setallocf is a stub", stderr); } -static int __lite_xl_fallback_lua_getstack (lua_State *L, int level, lua_Debug *ar) { fputs("warning: lua_getstack is a stub", stderr); } -static int __lite_xl_fallback_lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { fputs("warning: lua_getinfo is a stub", stderr); } -static const char * __lite_xl_fallback_lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { fputs("warning: lua_getlocal is a stub", stderr); } -static const char * __lite_xl_fallback_lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { fputs("warning: lua_setlocal is a stub", stderr); } -static const char * __lite_xl_fallback_lua_getupvalue (lua_State *L, int funcindex, int n) { fputs("warning: lua_getupvalue is a stub", stderr); } -static const char * __lite_xl_fallback_lua_setupvalue (lua_State *L, int funcindex, int n) { fputs("warning: lua_setupvalue is a stub", stderr); } -static void * __lite_xl_fallback_lua_upvalueid (lua_State *L, int fidx, int n) { fputs("warning: lua_upvalueid is a stub", stderr); } -static void __lite_xl_fallback_lua_upvaluejoin (lua_State *L, int fidx1, int n1, int fidx2, int n2) { fputs("warning: lua_upvaluejoin is a stub", stderr); } -static int __lite_xl_fallback_lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { fputs("warning: lua_sethook is a stub", stderr); } -static lua_Hook __lite_xl_fallback_lua_gethook (lua_State *L) { fputs("warning: lua_gethook is a stub", stderr); } -static int __lite_xl_fallback_lua_gethookmask (lua_State *L) { fputs("warning: lua_gethookmask is a stub", stderr); } -static int __lite_xl_fallback_lua_gethookcount (lua_State *L) { fputs("warning: lua_gethookcount is a stub", stderr); } - /** lauxlib.h **/ @@ -518,53 +456,54 @@ typedef struct luaL_Stream { FILE *f; lua_CFunction closef; } luaL_Stream; -static void (*luaL_checkversion_) (lua_State *L, lua_Number ver); -static int (*luaL_getmetafield) (lua_State *L, int obj, const char *e); -static int (*luaL_callmeta) (lua_State *L, int obj, const char *e); -static const char *(*luaL_tolstring) (lua_State *L, int idx, size_t *len); -static int (*luaL_argerror) (lua_State *L, int numarg, const char *extramsg); -static const char *(*luaL_checklstring) (lua_State *L, int numArg, size_t *l); -static const char *(*luaL_optlstring) (lua_State *L, int numArg, const char *def, size_t *l); -static lua_Number (*luaL_checknumber) (lua_State *L, int numArg); -static lua_Number (*luaL_optnumber) (lua_State *L, int nArg, lua_Number def); -static lua_Integer (*luaL_checkinteger) (lua_State *L, int numArg); -static lua_Integer (*luaL_optinteger) (lua_State *L, int nArg, lua_Integer def); -static lua_Unsigned (*luaL_checkunsigned) (lua_State *L, int numArg); -static lua_Unsigned (*luaL_optunsigned) (lua_State *L, int numArg, lua_Unsigned def); -static void (*luaL_checkstack) (lua_State *L, int sz, const char *msg); -static void (*luaL_checktype) (lua_State *L, int narg, int t); -static void (*luaL_checkany) (lua_State *L, int narg); -static int (*luaL_newmetatable) (lua_State *L, const char *tname); -static void (*luaL_setmetatable) (lua_State *L, const char *tname); -static void *(*luaL_testudata) (lua_State *L, int ud, const char *tname); -static void *(*luaL_checkudata) (lua_State *L, int ud, const char *tname); -static void (*luaL_where) (lua_State *L, int lvl); -static int (*luaL_error) (lua_State *L, const char *fmt, ...); -static int (*luaL_typeerror) (lua_State *L, int narg, const char *tname); -static int (*luaL_checkoption) (lua_State *L, int narg, const char *def, const char *const lst[]); -static int (*luaL_fileresult) (lua_State *L, int stat, const char *fname); -static int (*luaL_execresult) (lua_State *L, int stat); -static int (*luaL_ref) (lua_State *L, int t); -static void (*luaL_unref) (lua_State *L, int t, int ref); -static int (*luaL_loadfilex) (lua_State *L, const char *filename, const char *mode); -static int (*luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); -static int (*luaL_loadstring) (lua_State *L, const char *s); -static lua_State *(*luaL_newstate) (void); -static int (*luaL_len) (lua_State *L, int idx); -static const char *(*luaL_gsub) (lua_State *L, const char *s, const char *p, const char *r); -static void (*luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); -static int (*luaL_getsubtable) (lua_State *L, int idx, const char *fname); -static void (*luaL_traceback) (lua_State *L, lua_State *L1, const char *msg, int level); -static void (*luaL_requiref) (lua_State *L, const char *modname, lua_CFunction openf, int glb); -static void (*luaL_buffinit) (lua_State *L, luaL_Buffer *B); -static char *(*luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); -static void (*luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); -static void (*luaL_addstring) (luaL_Buffer *B, const char *s); -static void (*luaL_addvalue) (luaL_Buffer *B); -static void (*luaL_pushresult) (luaL_Buffer *B); -static void (*luaL_pushresultsize) (luaL_Buffer *B, size_t sz); -static char *(*luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); -static void (*luaL_openlibs) (lua_State *L); + +SYMBOL_DECLARE(void, luaL_checkversion_, lua_State *L, lua_Number ver) +SYMBOL_DECLARE(int, luaL_getmetafield, lua_State *L, int obj, const char *e) +SYMBOL_DECLARE(int, luaL_callmeta, lua_State *L, int obj, const char *e) +SYMBOL_DECLARE(const char *, luaL_tolstring, lua_State *L, int idx, size_t *len) +SYMBOL_DECLARE(int, luaL_argerror, lua_State *L, int numarg, const char *extramsg) +SYMBOL_DECLARE(const char *, luaL_checklstring, lua_State *L, int numArg, size_t *l) +SYMBOL_DECLARE(const char *, luaL_optlstring, lua_State *L, int numArg, const char *def, size_t *l) +SYMBOL_DECLARE(lua_Number, luaL_checknumber, lua_State *L, int numArg) +SYMBOL_DECLARE(lua_Number, luaL_optnumber, lua_State *L, int nArg, lua_Number def) +SYMBOL_DECLARE(lua_Integer, luaL_checkinteger, lua_State *L, int numArg) +SYMBOL_DECLARE(lua_Integer, luaL_optinteger, lua_State *L, int nArg, lua_Integer def) +SYMBOL_DECLARE(lua_Unsigned, luaL_checkunsigned, lua_State *L, int numArg) +SYMBOL_DECLARE(lua_Unsigned, luaL_optunsigned, lua_State *L, int numArg, lua_Unsigned def) +SYMBOL_DECLARE(void, luaL_checkstack, lua_State *L, int sz, const char *msg) +SYMBOL_DECLARE(void, luaL_checktype, lua_State *L, int narg, int t) +SYMBOL_DECLARE(void, luaL_checkany, lua_State *L, int narg) +SYMBOL_DECLARE(int, luaL_newmetatable, lua_State *L, const char *tname) +SYMBOL_DECLARE(void, luaL_setmetatable, lua_State *L, const char *tname) +SYMBOL_DECLARE(void *, luaL_testudata, lua_State *L, int ud, const char *tname) +SYMBOL_DECLARE(void *, luaL_checkudata, lua_State *L, int ud, const char *tname) +SYMBOL_DECLARE(void, luaL_where, lua_State *L, int lvl) +SYMBOL_DECLARE(int, luaL_error, lua_State *L, const char *fmt, ...) +SYMBOL_DECLARE(int, luaL_checkoption, lua_State *L, int narg, const char *def, const char *const lst[]) +SYMBOL_DECLARE(int, luaL_fileresult, lua_State *L, int stat, const char *fname) +SYMBOL_DECLARE(int, luaL_execresult, lua_State *L, int stat) +SYMBOL_DECLARE(int, luaL_ref, lua_State *L, int t) +SYMBOL_DECLARE(void, luaL_unref, lua_State *L, int t, int ref) +SYMBOL_DECLARE(int, luaL_loadfilex, lua_State *L, const char *filename, const char *mode) +SYMBOL_DECLARE(int, luaL_loadbufferx, lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) +SYMBOL_DECLARE(int, luaL_loadstring, lua_State *L, const char *s) +SYMBOL_DECLARE(lua_State *, luaL_newstate, void) +SYMBOL_DECLARE(int, luaL_len, lua_State *L, int idx) +SYMBOL_DECLARE(const char *, luaL_gsub, lua_State *L, const char *s, const char *p, const char *r) +SYMBOL_DECLARE(void, luaL_setfuncs, lua_State *L, const luaL_Reg *l, int nup) +SYMBOL_DECLARE(int, luaL_getsubtable, lua_State *L, int idx, const char *fname) +SYMBOL_DECLARE(void, luaL_traceback, lua_State *L, lua_State *L1, const char *msg, int level) +SYMBOL_DECLARE(void, luaL_requiref, lua_State *L, const char *modname, lua_CFunction openf, int glb) +SYMBOL_DECLARE(void, luaL_buffinit, lua_State *L, luaL_Buffer *B) +SYMBOL_DECLARE(char *, luaL_prepbuffsize, luaL_Buffer *B, size_t sz) +SYMBOL_DECLARE(void, luaL_addlstring, luaL_Buffer *B, const char *s, size_t l) +SYMBOL_DECLARE(void, luaL_addstring, luaL_Buffer *B, const char *s) +SYMBOL_DECLARE(void, luaL_addvalue, luaL_Buffer *B) +SYMBOL_DECLARE(void, luaL_pushresult, luaL_Buffer *B) +SYMBOL_DECLARE(void, luaL_pushresultsize, luaL_Buffer *B, size_t sz) +SYMBOL_DECLARE(char *, luaL_buffinitsize, lua_State *L, luaL_Buffer *B, size_t sz) +SYMBOL_DECLARE(void, luaL_openlibs, lua_State *L) + #define lauxlib_h #define LUA_ERRFILE (LUA_ERRERR+1) #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) @@ -590,194 +529,592 @@ static void (*luaL_openlibs) (lua_State *L); #define luaL_addsize(B,s) ((B)->n += (s)) #define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) #define LUA_FILEHANDLE "FILE*" -static void __lite_xl_fallback_luaL_checkversion_ (lua_State *L, lua_Number ver) { fputs("warning: luaL_checkversion_ is a stub", stderr); } -static int __lite_xl_fallback_luaL_getmetafield (lua_State *L, int obj, const char *e) { fputs("warning: luaL_getmetafield is a stub", stderr); } -static int __lite_xl_fallback_luaL_callmeta (lua_State *L, int obj, const char *e) { fputs("warning: luaL_callmeta is a stub", stderr); } -static const char * __lite_xl_fallback_luaL_tolstring (lua_State *L, int idx, size_t *len) { fputs("warning: luaL_tolstring is a stub", stderr); } -static int __lite_xl_fallback_luaL_argerror (lua_State *L, int numarg, const char *extramsg) { fputs("warning: luaL_argerror is a stub", stderr); } -static const char * __lite_xl_fallback_luaL_checklstring (lua_State *L, int numArg, size_t *l) { fputs("warning: luaL_checklstring is a stub", stderr); } -static const char * __lite_xl_fallback_luaL_optlstring (lua_State *L, int numArg, const char *def, size_t *l) { fputs("warning: luaL_optlstring is a stub", stderr); } -static lua_Number __lite_xl_fallback_luaL_checknumber (lua_State *L, int numArg) { fputs("warning: luaL_checknumber is a stub", stderr); } -static lua_Number __lite_xl_fallback_luaL_optnumber (lua_State *L, int nArg, lua_Number def) { fputs("warning: luaL_optnumber is a stub", stderr); } -static lua_Integer __lite_xl_fallback_luaL_checkinteger (lua_State *L, int numArg) { fputs("warning: luaL_checkinteger is a stub", stderr); } -static lua_Integer __lite_xl_fallback_luaL_optinteger (lua_State *L, int nArg, lua_Integer def) { fputs("warning: luaL_optinteger is a stub", stderr); } -static lua_Unsigned __lite_xl_fallback_luaL_checkunsigned (lua_State *L, int numArg) { fputs("warning: luaL_checkunsigned is a stub", stderr); } -static lua_Unsigned __lite_xl_fallback_luaL_optunsigned (lua_State *L, int numArg, lua_Unsigned def) { fputs("warning: luaL_optunsigned is a stub", stderr); } -static void __lite_xl_fallback_luaL_checkstack (lua_State *L, int sz, const char *msg) { fputs("warning: luaL_checkstack is a stub", stderr); } -static void __lite_xl_fallback_luaL_checktype (lua_State *L, int narg, int t) { fputs("warning: luaL_checktype is a stub", stderr); } -static void __lite_xl_fallback_luaL_checkany (lua_State *L, int narg) { fputs("warning: luaL_checkany is a stub", stderr); } -static int __lite_xl_fallback_luaL_newmetatable (lua_State *L, const char *tname) { fputs("warning: luaL_newmetatable is a stub", stderr); } -static void __lite_xl_fallback_luaL_setmetatable (lua_State *L, const char *tname) { fputs("warning: luaL_setmetatable is a stub", stderr); } -static void * __lite_xl_fallback_luaL_testudata (lua_State *L, int ud, const char *tname) { fputs("warning: luaL_testudata is a stub", stderr); } -static void * __lite_xl_fallback_luaL_checkudata (lua_State *L, int ud, const char *tname) { fputs("warning: luaL_checkudata is a stub", stderr); } -static void __lite_xl_fallback_luaL_where (lua_State *L, int lvl) { fputs("warning: luaL_where is a stub", stderr); } -static int __lite_xl_fallback_luaL_error (lua_State *L, const char *fmt, ...) { fputs("warning: luaL_error is a stub", stderr); } -static int __lite_xl_fallback_luaL_typeerror (lua_State *L, int narg, const char *tname) { fputs("warning: luaL_typeerror is a stub", stderr); } -static int __lite_xl_fallback_luaL_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]) { fputs("warning: luaL_checkoption is a stub", stderr); } -static int __lite_xl_fallback_luaL_fileresult (lua_State *L, int stat, const char *fname) { fputs("warning: luaL_fileresult is a stub", stderr); } -static int __lite_xl_fallback_luaL_execresult (lua_State *L, int stat) { fputs("warning: luaL_execresult is a stub", stderr); } -static int __lite_xl_fallback_luaL_ref (lua_State *L, int t) { fputs("warning: luaL_ref is a stub", stderr); } -static void __lite_xl_fallback_luaL_unref (lua_State *L, int t, int ref) { fputs("warning: luaL_unref is a stub", stderr); } -static int __lite_xl_fallback_luaL_loadfilex (lua_State *L, const char *filename, const char *mode) { fputs("warning: luaL_loadfilex is a stub", stderr); } -static int __lite_xl_fallback_luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) { fputs("warning: luaL_loadbufferx is a stub", stderr); } -static int __lite_xl_fallback_luaL_loadstring (lua_State *L, const char *s) { fputs("warning: luaL_loadstring is a stub", stderr); } -static lua_State * __lite_xl_fallback_luaL_newstate (void) { fputs("warning: luaL_newstate is a stub", stderr); } -static int __lite_xl_fallback_luaL_len (lua_State *L, int idx) { fputs("warning: luaL_len is a stub", stderr); } -static const char * __lite_xl_fallback_luaL_gsub (lua_State *L, const char *s, const char *p, const char *r) { fputs("warning: luaL_gsub is a stub", stderr); } -static void __lite_xl_fallback_luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { fputs("warning: luaL_setfuncs is a stub", stderr); } -static int __lite_xl_fallback_luaL_getsubtable (lua_State *L, int idx, const char *fname) { fputs("warning: luaL_getsubtable is a stub", stderr); } -static void __lite_xl_fallback_luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level) { fputs("warning: luaL_traceback is a stub", stderr); } -static void __lite_xl_fallback_luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb) { fputs("warning: luaL_requiref is a stub", stderr); } -static void __lite_xl_fallback_luaL_buffinit (lua_State *L, luaL_Buffer *B) { fputs("warning: luaL_buffinit is a stub", stderr); } -static char * __lite_xl_fallback_luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { fputs("warning: luaL_prepbuffsize is a stub", stderr); } -static void __lite_xl_fallback_luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { fputs("warning: luaL_addlstring is a stub", stderr); } -static void __lite_xl_fallback_luaL_addstring (luaL_Buffer *B, const char *s) { fputs("warning: luaL_addstring is a stub", stderr); } -static void __lite_xl_fallback_luaL_addvalue (luaL_Buffer *B) { fputs("warning: luaL_addvalue is a stub", stderr); } -static void __lite_xl_fallback_luaL_pushresult (luaL_Buffer *B) { fputs("warning: luaL_pushresult is a stub", stderr); } -static void __lite_xl_fallback_luaL_pushresultsize (luaL_Buffer *B, size_t sz) { fputs("warning: luaL_pushresultsize is a stub", stderr); } -static char * __lite_xl_fallback_luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { fputs("warning: luaL_buffinitsize is a stub", stderr); } -static void __lite_xl_fallback_luaL_openlibs (lua_State *L) { fputs("warning: luaL_openlibs is a stub", stderr); } -#define IMPORT_SYMBOL(name, ret, ...) name = (name = (ret (*) (__VA_ARGS__)) symbol(#name), name == NULL ? &__lite_xl_fallback_##name : name) -static void lite_xl_plugin_init(void *XL) { - void* (*symbol)(const char *) = (void* (*) (const char *)) XL; - IMPORT_SYMBOL(lua_newstate, lua_State *, lua_Alloc f, void *ud); - IMPORT_SYMBOL(lua_close, void , lua_State *L); - IMPORT_SYMBOL(lua_newthread, lua_State *, lua_State *L); - IMPORT_SYMBOL(lua_atpanic, lua_CFunction , lua_State *L, lua_CFunction panicf); - IMPORT_SYMBOL(lua_version, const lua_Number *, lua_State *L); - IMPORT_SYMBOL(lua_absindex, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_gettop, int , lua_State *L); - IMPORT_SYMBOL(lua_settop, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_pushvalue, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_copy, void , lua_State *L, int fromidx, int toidx); - IMPORT_SYMBOL(lua_checkstack, int , lua_State *L, int sz); - IMPORT_SYMBOL(lua_xmove, void , lua_State *from, lua_State *to, int n); - IMPORT_SYMBOL(lua_isnumber, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_isstring, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_iscfunction, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_isuserdata, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_type, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_typename, const char *, lua_State *L, int tp); - IMPORT_SYMBOL(lua_tonumberx, lua_Number , lua_State *L, int idx, int *isnum); - IMPORT_SYMBOL(lua_tointegerx, lua_Integer , lua_State *L, int idx, int *isnum); - IMPORT_SYMBOL(lua_tounsignedx, lua_Unsigned , lua_State *L, int idx, int *isnum); - IMPORT_SYMBOL(lua_toboolean, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_tolstring, const char *, lua_State *L, int idx, size_t *len); - IMPORT_SYMBOL(lua_rawlen, size_t , lua_State *L, int idx); - IMPORT_SYMBOL(lua_tocfunction, lua_CFunction , lua_State *L, int idx); - IMPORT_SYMBOL(lua_touserdata, void *, lua_State *L, int idx); - IMPORT_SYMBOL(lua_tothread, lua_State *, lua_State *L, int idx); - IMPORT_SYMBOL(lua_topointer, const void *, lua_State *L, int idx); - IMPORT_SYMBOL(lua_arith, void , lua_State *L, int op); - IMPORT_SYMBOL(lua_rawequal, int , lua_State *L, int idx1, int idx2); - IMPORT_SYMBOL(lua_compare, int , lua_State *L, int idx1, int idx2, int op); - IMPORT_SYMBOL(lua_pushnil, void , lua_State *L); - IMPORT_SYMBOL(lua_pushnumber, void , lua_State *L, lua_Number n); - IMPORT_SYMBOL(lua_pushinteger, void , lua_State *L, lua_Integer n); - IMPORT_SYMBOL(lua_pushunsigned, void , lua_State *L, lua_Unsigned n); - IMPORT_SYMBOL(lua_pushlstring, const char *, lua_State *L, const char *s, size_t l); - IMPORT_SYMBOL(lua_pushstring, const char *, lua_State *L, const char *s); - IMPORT_SYMBOL(lua_pushvfstring, const char *, lua_State *L, const char *fmt, va_list argp); - IMPORT_SYMBOL(lua_pushfstring, const char *, lua_State *L, const char *fmt, ...); - IMPORT_SYMBOL(lua_pushcclosure, void , lua_State *L, lua_CFunction fn, int n); - IMPORT_SYMBOL(lua_pushboolean, void , lua_State *L, int b); - IMPORT_SYMBOL(lua_pushlightuserdata, void , lua_State *L, void *p); - IMPORT_SYMBOL(lua_pushthread, int , lua_State *L); - IMPORT_SYMBOL(lua_getglobal, void , lua_State *L, const char *var); - IMPORT_SYMBOL(lua_gettable, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_getfield, void , lua_State *L, int idx, const char *k); - IMPORT_SYMBOL(lua_rawget, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_rawgeti, void , lua_State *L, int idx, int n); - IMPORT_SYMBOL(lua_rawgetp, void , lua_State *L, int idx, const void *p); - IMPORT_SYMBOL(lua_createtable, void , lua_State *L, int narr, int nrec); - IMPORT_SYMBOL(lua_newuserdata, void *, lua_State *L, size_t sz); - IMPORT_SYMBOL(lua_newuserdatauv, void *, lua_State *L, size_t sz, int nuvalue); - IMPORT_SYMBOL(lua_getmetatable, int , lua_State *L, int objindex); - IMPORT_SYMBOL(lua_getuservalue, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_getiuservalue, void , lua_State *L, int idx, int n); - IMPORT_SYMBOL(lua_setglobal, void , lua_State *L, const char *var); - IMPORT_SYMBOL(lua_settable, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_setfield, void , lua_State *L, int idx, const char *k); - IMPORT_SYMBOL(lua_rawset, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_rawseti, void , lua_State *L, int idx, int n); - IMPORT_SYMBOL(lua_rawsetp, void , lua_State *L, int idx, const void *p); - IMPORT_SYMBOL(lua_setmetatable, int , lua_State *L, int objindex); - IMPORT_SYMBOL(lua_setuservalue, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_setiuservalue, void , lua_State *L, int idx, int n); - IMPORT_SYMBOL(lua_callk, void , lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k); - IMPORT_SYMBOL(lua_getctx, int , lua_State *L, int *ctx); - IMPORT_SYMBOL(lua_pcallk, int , lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k); - IMPORT_SYMBOL(lua_load, int , lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); - IMPORT_SYMBOL(lua_dump, int , lua_State *L, lua_Writer writer, void *data, int strip); - IMPORT_SYMBOL(lua_yieldk, int , lua_State *L, int nresults, int ctx, lua_CFunction k); - IMPORT_SYMBOL(lua_resume, int , lua_State *L, lua_State *from, int narg); - IMPORT_SYMBOL(lua_status, int , lua_State *L); - IMPORT_SYMBOL(lua_gc, int , lua_State *L, int what, int data); - IMPORT_SYMBOL(lua_error, int , lua_State *L); - IMPORT_SYMBOL(lua_next, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_concat, void , lua_State *L, int n); - IMPORT_SYMBOL(lua_len, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_getallocf, lua_Alloc , lua_State *L, void **ud); - IMPORT_SYMBOL(lua_setallocf, void , lua_State *L, lua_Alloc f, void *ud); - IMPORT_SYMBOL(lua_getstack, int , lua_State *L, int level, lua_Debug *ar); - IMPORT_SYMBOL(lua_getinfo, int , lua_State *L, const char *what, lua_Debug *ar); - IMPORT_SYMBOL(lua_getlocal, const char *, lua_State *L, const lua_Debug *ar, int n); - IMPORT_SYMBOL(lua_setlocal, const char *, lua_State *L, const lua_Debug *ar, int n); - IMPORT_SYMBOL(lua_getupvalue, const char *, lua_State *L, int funcindex, int n); - IMPORT_SYMBOL(lua_setupvalue, const char *, lua_State *L, int funcindex, int n); - IMPORT_SYMBOL(lua_upvalueid, void *, lua_State *L, int fidx, int n); - IMPORT_SYMBOL(lua_upvaluejoin, void , lua_State *L, int fidx1, int n1, int fidx2, int n2); - IMPORT_SYMBOL(lua_sethook, int , lua_State *L, lua_Hook func, int mask, int count); - IMPORT_SYMBOL(lua_gethook, lua_Hook , lua_State *L); - IMPORT_SYMBOL(lua_gethookmask, int , lua_State *L); - IMPORT_SYMBOL(lua_gethookcount, int , lua_State *L); - IMPORT_SYMBOL(luaL_checkversion_, void , lua_State *L, lua_Number ver); - IMPORT_SYMBOL(luaL_getmetafield, int , lua_State *L, int obj, const char *e); - IMPORT_SYMBOL(luaL_callmeta, int , lua_State *L, int obj, const char *e); - IMPORT_SYMBOL(luaL_tolstring, const char *, lua_State *L, int idx, size_t *len); - IMPORT_SYMBOL(luaL_argerror, int , lua_State *L, int numarg, const char *extramsg); - IMPORT_SYMBOL(luaL_checklstring, const char *, lua_State *L, int numArg, size_t *l); - IMPORT_SYMBOL(luaL_optlstring, const char *, lua_State *L, int numArg, const char *def, size_t *l); - IMPORT_SYMBOL(luaL_checknumber, lua_Number , lua_State *L, int numArg); - IMPORT_SYMBOL(luaL_optnumber, lua_Number , lua_State *L, int nArg, lua_Number def); - IMPORT_SYMBOL(luaL_checkinteger, lua_Integer , lua_State *L, int numArg); - IMPORT_SYMBOL(luaL_optinteger, lua_Integer , lua_State *L, int nArg, lua_Integer def); - IMPORT_SYMBOL(luaL_checkunsigned, lua_Unsigned , lua_State *L, int numArg); - IMPORT_SYMBOL(luaL_optunsigned, lua_Unsigned , lua_State *L, int numArg, lua_Unsigned def); - IMPORT_SYMBOL(luaL_checkstack, void , lua_State *L, int sz, const char *msg); - IMPORT_SYMBOL(luaL_checktype, void , lua_State *L, int narg, int t); - IMPORT_SYMBOL(luaL_checkany, void , lua_State *L, int narg); - IMPORT_SYMBOL(luaL_newmetatable, int , lua_State *L, const char *tname); - IMPORT_SYMBOL(luaL_setmetatable, void , lua_State *L, const char *tname); - IMPORT_SYMBOL(luaL_testudata, void *, lua_State *L, int ud, const char *tname); - IMPORT_SYMBOL(luaL_checkudata, void *, lua_State *L, int ud, const char *tname); - IMPORT_SYMBOL(luaL_where, void , lua_State *L, int lvl); - IMPORT_SYMBOL(luaL_error, int , lua_State *L, const char *fmt, ...); - IMPORT_SYMBOL(luaL_typeerror, int , lua_State *L, int narg, const char *tname); - IMPORT_SYMBOL(luaL_checkoption, int , lua_State *L, int narg, const char *def, const char *const lst[]); - IMPORT_SYMBOL(luaL_fileresult, int , lua_State *L, int stat, const char *fname); - IMPORT_SYMBOL(luaL_execresult, int , lua_State *L, int stat); - IMPORT_SYMBOL(luaL_ref, int , lua_State *L, int t); - IMPORT_SYMBOL(luaL_unref, void , lua_State *L, int t, int ref); - IMPORT_SYMBOL(luaL_loadfilex, int , lua_State *L, const char *filename, const char *mode); - IMPORT_SYMBOL(luaL_loadbufferx, int , lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); - IMPORT_SYMBOL(luaL_loadstring, int , lua_State *L, const char *s); - IMPORT_SYMBOL(luaL_newstate, lua_State *, void); - IMPORT_SYMBOL(luaL_len, int , lua_State *L, int idx); - IMPORT_SYMBOL(luaL_gsub, const char *, lua_State *L, const char *s, const char *p, const char *r); - IMPORT_SYMBOL(luaL_setfuncs, void , lua_State *L, const luaL_Reg *l, int nup); - IMPORT_SYMBOL(luaL_getsubtable, int , lua_State *L, int idx, const char *fname); - IMPORT_SYMBOL(luaL_traceback, void , lua_State *L, lua_State *L1, const char *msg, int level); - IMPORT_SYMBOL(luaL_requiref, void , lua_State *L, const char *modname, lua_CFunction openf, int glb); - IMPORT_SYMBOL(luaL_buffinit, void , lua_State *L, luaL_Buffer *B); - IMPORT_SYMBOL(luaL_prepbuffsize, char *, luaL_Buffer *B, size_t sz); - IMPORT_SYMBOL(luaL_addlstring, void , luaL_Buffer *B, const char *s, size_t l); - IMPORT_SYMBOL(luaL_addstring, void , luaL_Buffer *B, const char *s); - IMPORT_SYMBOL(luaL_addvalue, void , luaL_Buffer *B); - IMPORT_SYMBOL(luaL_pushresult, void , luaL_Buffer *B); - IMPORT_SYMBOL(luaL_pushresultsize, void , luaL_Buffer *B, size_t sz); - IMPORT_SYMBOL(luaL_buffinitsize, char *, lua_State *L, luaL_Buffer *B, size_t sz); - IMPORT_SYMBOL(luaL_openlibs, void, lua_State* L); +#ifdef LITE_XL_PLUGIN_ENTRYPOINT + +SYMBOL_WRAP_DECL(lua_State *, lua_newstate, lua_Alloc f, void *ud){ + SYMBOL_WRAP_CALL(lua_newstate, f, ud); } -#endif +SYMBOL_WRAP_DECL(void, lua_close, lua_State *L){ + SYMBOL_WRAP_CALL(lua_close, L); +} +SYMBOL_WRAP_DECL(lua_State *, lua_newthread, lua_State *L){ + SYMBOL_WRAP_CALL(lua_newthread, L); +} +SYMBOL_WRAP_DECL(lua_CFunction, lua_atpanic, lua_State *L, lua_CFunction panicf){ + SYMBOL_WRAP_CALL(lua_atpanic, L, panicf); +} +SYMBOL_WRAP_DECL(const lua_Number *, lua_version, lua_State *L){ + SYMBOL_WRAP_CALL(lua_version, L); +} +SYMBOL_WRAP_DECL(int, lua_absindex, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_absindex, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_gettop, lua_State *L){ + SYMBOL_WRAP_CALL(lua_gettop, L); +} +SYMBOL_WRAP_DECL(void, lua_settop, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_settop, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_pushvalue, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_pushvalue, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_copy, lua_State *L, int fromidx, int toidx){ + SYMBOL_WRAP_CALL(lua_copy, L, fromidx, toidx); +} +SYMBOL_WRAP_DECL(int, lua_checkstack, lua_State *L, int sz){ + SYMBOL_WRAP_CALL(lua_checkstack, L, sz); +} +SYMBOL_WRAP_DECL(void, lua_xmove, lua_State *from, lua_State *to, int n){ + SYMBOL_WRAP_CALL(lua_xmove, from, to, n); +} +SYMBOL_WRAP_DECL(int, lua_isnumber, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_isnumber, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_isstring, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_isstring, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_iscfunction, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_iscfunction, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_isuserdata, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_isuserdata, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_type, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_type, L, idx); +} +SYMBOL_WRAP_DECL(const char *, lua_typename, lua_State *L, int tp){ + SYMBOL_WRAP_CALL(lua_typename, L, tp); +} +SYMBOL_WRAP_DECL(lua_Number, lua_tonumberx, lua_State *L, int idx, int *isnum){ + SYMBOL_WRAP_CALL(lua_tonumberx, L, idx, isnum); +} +SYMBOL_WRAP_DECL(lua_Integer, lua_tointegerx, lua_State *L, int idx, int *isnum){ + SYMBOL_WRAP_CALL(lua_tointegerx, L, idx, isnum); +} +SYMBOL_WRAP_DECL(lua_Unsigned, lua_tounsignedx, lua_State *L, int idx, int *isnum){ + SYMBOL_WRAP_CALL(lua_tounsignedx, L, idx, isnum); +} +SYMBOL_WRAP_DECL(int, lua_toboolean, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_toboolean, L, idx); +} +SYMBOL_WRAP_DECL(const char *, lua_tolstring, lua_State *L, int idx, size_t *len){ + SYMBOL_WRAP_CALL(lua_tolstring, L, idx, len); +} +SYMBOL_WRAP_DECL(size_t, lua_rawlen, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_rawlen, L, idx); +} +SYMBOL_WRAP_DECL(lua_CFunction, lua_tocfunction, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_tocfunction, L, idx); +} +SYMBOL_WRAP_DECL(void *, lua_touserdata, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_touserdata, L, idx); +} +SYMBOL_WRAP_DECL(lua_State *, lua_tothread, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_tothread, L, idx); +} +SYMBOL_WRAP_DECL(const void *, lua_topointer, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_topointer, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_arith, lua_State *L, int op){ + SYMBOL_WRAP_CALL(lua_arith, L, op); +} +SYMBOL_WRAP_DECL(int, lua_rawequal, lua_State *L, int idx1, int idx2){ + SYMBOL_WRAP_CALL(lua_rawequal, L, idx1, idx2); +} +SYMBOL_WRAP_DECL(int, lua_compare, lua_State *L, int idx1, int idx2, int op){ + SYMBOL_WRAP_CALL(lua_compare, L, idx1, idx2, op); +} +SYMBOL_WRAP_DECL(void, lua_pushnil, lua_State *L){ + SYMBOL_WRAP_CALL(lua_pushnil, L); +} +SYMBOL_WRAP_DECL(void, lua_pushnumber, lua_State *L, lua_Number n){ + SYMBOL_WRAP_CALL(lua_pushnumber, L, n); +} +SYMBOL_WRAP_DECL(void, lua_pushinteger, lua_State *L, lua_Integer n){ + SYMBOL_WRAP_CALL(lua_pushinteger, L, n); +} +SYMBOL_WRAP_DECL(void, lua_pushunsigned, lua_State *L, lua_Unsigned n){ + SYMBOL_WRAP_CALL(lua_pushunsigned, L, n); +} +SYMBOL_WRAP_DECL(const char *, lua_pushlstring, lua_State *L, const char *s, size_t l){ + SYMBOL_WRAP_CALL(lua_pushlstring, L, s, l); +} +SYMBOL_WRAP_DECL(const char *, lua_pushstring, lua_State *L, const char *s){ + SYMBOL_WRAP_CALL(lua_pushstring, L, s); +} +SYMBOL_WRAP_DECL(const char *, lua_pushvfstring, lua_State *L, const char *fmt, va_list argp){ + SYMBOL_WRAP_CALL(lua_pushvfstring, L, fmt, argp); +} +SYMBOL_WRAP_DECL(const char *, lua_pushfstring, lua_State *L, const char *fmt, ...){ + SYMBOL_WRAP_CALL(lua_pushfstring, L, fmt); +} +SYMBOL_WRAP_DECL(void, lua_pushcclosure, lua_State *L, lua_CFunction fn, int n){ + SYMBOL_WRAP_CALL(lua_pushcclosure, L, fn, n); +} +SYMBOL_WRAP_DECL(void, lua_pushboolean, lua_State *L, int b){ + SYMBOL_WRAP_CALL(lua_pushboolean, L, b); +} +SYMBOL_WRAP_DECL(void, lua_pushlightuserdata, lua_State *L, void *p){ + SYMBOL_WRAP_CALL(lua_pushlightuserdata, L, p); +} +SYMBOL_WRAP_DECL(int, lua_pushthread, lua_State *L){ + SYMBOL_WRAP_CALL(lua_pushthread, L); +} +SYMBOL_WRAP_DECL(void, lua_getglobal, lua_State *L, const char *var){ + SYMBOL_WRAP_CALL(lua_getglobal, L, var); +} +SYMBOL_WRAP_DECL(void, lua_gettable, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_gettable, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_getfield, lua_State *L, int idx, const char *k){ + SYMBOL_WRAP_CALL(lua_getfield, L, idx, k); +} +SYMBOL_WRAP_DECL(void, lua_rawget, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_rawget, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_rawgeti, lua_State *L, int idx, int n){ + SYMBOL_WRAP_CALL(lua_rawgeti, L, idx, n); +} +SYMBOL_WRAP_DECL(void, lua_rawgetp, lua_State *L, int idx, const void *p){ + SYMBOL_WRAP_CALL(lua_rawgetp, L, idx, p); +} +SYMBOL_WRAP_DECL(void, lua_createtable, lua_State *L, int narr, int nrec){ + SYMBOL_WRAP_CALL(lua_createtable, L, narr, nrec); +} +SYMBOL_WRAP_DECL(void *, lua_newuserdata, lua_State *L, size_t sz){ + if (__lua_newuserdatauv != NULL) { + return lua_newuserdatauv(L, sz, 1); + } else if (__lua_newuserdata != NULL) { + SYMBOL_WRAP_CALL(lua_newuserdata, L, sz); + } + SYMBOL_WRAP_CALL_FB(lua_newuserdata, L, sz); +} +SYMBOL_WRAP_DECL(void *, lua_newuserdatauv, lua_State *L, size_t sz, int nuvalue){ + SYMBOL_WRAP_CALL(lua_newuserdatauv, L, sz, nuvalue); +} +SYMBOL_WRAP_DECL(int, lua_getmetatable, lua_State *L, int objindex){ + SYMBOL_WRAP_CALL(lua_getmetatable, L, objindex); +} +SYMBOL_WRAP_DECL(void, lua_getuservalue, lua_State *L, int idx){ + if (__lua_getiuservalue != NULL) { + return lua_getiuservalue(L, idx, 1); + } else if (__lua_getuservalue != NULL) { + SYMBOL_WRAP_CALL(lua_getuservalue, L, idx); + } + SYMBOL_WRAP_CALL_FB(lua_getuservalue, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_getiuservalue, lua_State *L, int idx, int n){ + SYMBOL_WRAP_CALL(lua_getiuservalue, L, idx, n); +} +SYMBOL_WRAP_DECL(void, lua_setglobal, lua_State *L, const char *var){ + SYMBOL_WRAP_CALL(lua_setglobal, L, var); +} +SYMBOL_WRAP_DECL(void, lua_settable, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_settable, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_setfield, lua_State *L, int idx, const char *k){ + SYMBOL_WRAP_CALL(lua_setfield, L, idx, k); +} +SYMBOL_WRAP_DECL(void, lua_rawset, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_rawset, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_rawseti, lua_State *L, int idx, int n){ + SYMBOL_WRAP_CALL(lua_rawseti, L, idx, n); +} +SYMBOL_WRAP_DECL(void, lua_rawsetp, lua_State *L, int idx, const void *p){ + SYMBOL_WRAP_CALL(lua_rawsetp, L, idx, p); +} +SYMBOL_WRAP_DECL(int, lua_setmetatable, lua_State *L, int objindex){ + SYMBOL_WRAP_CALL(lua_setmetatable, L, objindex); +} +SYMBOL_WRAP_DECL(void, lua_setuservalue, lua_State *L, int idx){ + if (__lua_setiuservalue != NULL) { + return lua_setiuservalue(L, idx, 1); + } else if (__lua_setuservalue != NULL) { + SYMBOL_WRAP_CALL(lua_setuservalue, L, idx); + } + SYMBOL_WRAP_CALL_FB(lua_setuservalue, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_setiuservalue, lua_State *L, int idx, int n){ + SYMBOL_WRAP_CALL(lua_setiuservalue, L, idx, n); +} +SYMBOL_WRAP_DECL(void, lua_callk, lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k){ + SYMBOL_WRAP_CALL(lua_callk, L, nargs, nresults, ctx, k); +} +SYMBOL_WRAP_DECL(int, lua_getctx, lua_State *L, int *ctx){ + SYMBOL_WRAP_CALL(lua_getctx, L, ctx); +} +SYMBOL_WRAP_DECL(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k){ + SYMBOL_WRAP_CALL(lua_pcallk, L, nargs, nresults, errfunc, ctx, k); +} +SYMBOL_WRAP_DECL(int, lua_load, lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode){ + SYMBOL_WRAP_CALL(lua_load, L, reader, dt, chunkname, mode); +} +SYMBOL_WRAP_DECL(int, lua_dump, lua_State *L, lua_Writer writer, void *data, int strip){ + SYMBOL_WRAP_CALL(lua_dump, L, writer, data, strip); +} +SYMBOL_WRAP_DECL(int, lua_yieldk, lua_State *L, int nresults, int ctx, lua_CFunction k){ + SYMBOL_WRAP_CALL(lua_yieldk, L, nresults, ctx, k); +} +SYMBOL_WRAP_DECL(int, lua_resume, lua_State *L, lua_State *from, int narg){ + SYMBOL_WRAP_CALL(lua_resume, L, from, narg); +} +SYMBOL_WRAP_DECL(int, lua_status, lua_State *L){ + SYMBOL_WRAP_CALL(lua_status, L); +} +SYMBOL_WRAP_DECL(int, lua_gc, lua_State *L, int what, int data){ + SYMBOL_WRAP_CALL(lua_gc, L, what, data); +} +SYMBOL_WRAP_DECL(int, lua_error, lua_State *L){ + SYMBOL_WRAP_CALL(lua_error, L); +} +SYMBOL_WRAP_DECL(int, lua_next, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_next, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_concat, lua_State *L, int n){ + SYMBOL_WRAP_CALL(lua_concat, L, n); +} +SYMBOL_WRAP_DECL(void, lua_len, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(lua_len, L, idx); +} +SYMBOL_WRAP_DECL(lua_Alloc, lua_getallocf, lua_State *L, void **ud){ + SYMBOL_WRAP_CALL(lua_getallocf, L, ud); +} +SYMBOL_WRAP_DECL(void, lua_setallocf, lua_State *L, lua_Alloc f, void *ud){ + SYMBOL_WRAP_CALL(lua_setallocf, L, f, ud); +} +SYMBOL_WRAP_DECL(int, lua_getstack, lua_State *L, int level, lua_Debug *ar){ + SYMBOL_WRAP_CALL(lua_getstack, L, level, ar); +} +SYMBOL_WRAP_DECL(int, lua_getinfo, lua_State *L, const char *what, lua_Debug *ar){ + SYMBOL_WRAP_CALL(lua_getinfo, L, what, ar); +} +SYMBOL_WRAP_DECL(const char *, lua_getlocal, lua_State *L, const lua_Debug *ar, int n){ + SYMBOL_WRAP_CALL(lua_getlocal, L, ar, n); +} +SYMBOL_WRAP_DECL(const char *, lua_setlocal, lua_State *L, const lua_Debug *ar, int n){ + SYMBOL_WRAP_CALL(lua_setlocal, L, ar, n); +} +SYMBOL_WRAP_DECL(const char *, lua_getupvalue, lua_State *L, int funcindex, int n){ + SYMBOL_WRAP_CALL(lua_getupvalue, L, funcindex, n); +} +SYMBOL_WRAP_DECL(const char *, lua_setupvalue, lua_State *L, int funcindex, int n){ + SYMBOL_WRAP_CALL(lua_setupvalue, L, funcindex, n); +} +SYMBOL_WRAP_DECL(void *, lua_upvalueid, lua_State *L, int fidx, int n){ + SYMBOL_WRAP_CALL(lua_upvalueid, L, fidx, n); +} +SYMBOL_WRAP_DECL(void, lua_upvaluejoin, lua_State *L, int fidx1, int n1, int fidx2, int n2){ + SYMBOL_WRAP_CALL(lua_upvaluejoin, L, fidx1, n1, fidx2, n2); +} +SYMBOL_WRAP_DECL(int, lua_sethook, lua_State *L, lua_Hook func, int mask, int count){ + SYMBOL_WRAP_CALL(lua_sethook, L, func, mask, count); +} +SYMBOL_WRAP_DECL(lua_Hook, lua_gethook, lua_State *L){ + SYMBOL_WRAP_CALL(lua_gethook, L); +} +SYMBOL_WRAP_DECL(int, lua_gethookmask, lua_State *L){ + SYMBOL_WRAP_CALL(lua_gethookmask, L); +} +SYMBOL_WRAP_DECL(int, lua_gethookcount, lua_State *L){ + SYMBOL_WRAP_CALL(lua_gethookcount, L); +} +SYMBOL_WRAP_DECL(void, luaL_checkversion_, lua_State *L, lua_Number ver){ + SYMBOL_WRAP_CALL(luaL_checkversion_, L, ver); +} +SYMBOL_WRAP_DECL(int, luaL_getmetafield, lua_State *L, int obj, const char *e){ + SYMBOL_WRAP_CALL(luaL_getmetafield, L, obj, e); +} +SYMBOL_WRAP_DECL(int, luaL_callmeta, lua_State *L, int obj, const char *e){ + SYMBOL_WRAP_CALL(luaL_callmeta, L, obj, e); +} +SYMBOL_WRAP_DECL(const char *, luaL_tolstring, lua_State *L, int idx, size_t *len){ + SYMBOL_WRAP_CALL(luaL_tolstring, L, idx, len); +} +SYMBOL_WRAP_DECL(int, luaL_argerror, lua_State *L, int numarg, const char *extramsg){ + SYMBOL_WRAP_CALL(luaL_argerror, L, numarg, extramsg); +} +SYMBOL_WRAP_DECL(const char *, luaL_checklstring, lua_State *L, int numArg, size_t *l){ + SYMBOL_WRAP_CALL(luaL_checklstring, L, numArg, l); +} +SYMBOL_WRAP_DECL(const char *, luaL_optlstring, lua_State *L, int numArg, const char *def, size_t *l){ + SYMBOL_WRAP_CALL(luaL_optlstring, L, numArg, def, l); +} +SYMBOL_WRAP_DECL(lua_Number, luaL_checknumber, lua_State *L, int numArg){ + SYMBOL_WRAP_CALL(luaL_checknumber, L, numArg); +} +SYMBOL_WRAP_DECL(lua_Number, luaL_optnumber, lua_State *L, int nArg, lua_Number def){ + SYMBOL_WRAP_CALL(luaL_optnumber, L, nArg, def); +} +SYMBOL_WRAP_DECL(lua_Integer, luaL_checkinteger, lua_State *L, int numArg){ + SYMBOL_WRAP_CALL(luaL_checkinteger, L, numArg); +} +SYMBOL_WRAP_DECL(lua_Integer, luaL_optinteger, lua_State *L, int nArg, lua_Integer def){ + SYMBOL_WRAP_CALL(luaL_optinteger, L, nArg, def); +} +SYMBOL_WRAP_DECL(lua_Unsigned, luaL_checkunsigned, lua_State *L, int numArg){ + SYMBOL_WRAP_CALL(luaL_checkunsigned, L, numArg); +} +SYMBOL_WRAP_DECL(lua_Unsigned, luaL_optunsigned, lua_State *L, int numArg, lua_Unsigned def){ + SYMBOL_WRAP_CALL(luaL_optunsigned, L, numArg, def); +} +SYMBOL_WRAP_DECL(void, luaL_checkstack, lua_State *L, int sz, const char *msg){ + SYMBOL_WRAP_CALL(luaL_checkstack, L, sz, msg); +} +SYMBOL_WRAP_DECL(void, luaL_checktype, lua_State *L, int narg, int t){ + SYMBOL_WRAP_CALL(luaL_checktype, L, narg, t); +} +SYMBOL_WRAP_DECL(void, luaL_checkany, lua_State *L, int narg){ + SYMBOL_WRAP_CALL(luaL_checkany, L, narg); +} +SYMBOL_WRAP_DECL(int, luaL_newmetatable, lua_State *L, const char *tname){ + SYMBOL_WRAP_CALL(luaL_newmetatable, L, tname); +} +SYMBOL_WRAP_DECL(void, luaL_setmetatable, lua_State *L, const char *tname){ + SYMBOL_WRAP_CALL(luaL_setmetatable, L, tname); +} +SYMBOL_WRAP_DECL(void *, luaL_testudata, lua_State *L, int ud, const char *tname){ + SYMBOL_WRAP_CALL(luaL_testudata, L, ud, tname); +} +SYMBOL_WRAP_DECL(void *, luaL_checkudata, lua_State *L, int ud, const char *tname){ + SYMBOL_WRAP_CALL(luaL_checkudata, L, ud, tname); +} +SYMBOL_WRAP_DECL(void, luaL_where, lua_State *L, int lvl){ + SYMBOL_WRAP_CALL(luaL_where, L, lvl); +} +SYMBOL_WRAP_DECL(int, luaL_error, lua_State *L, const char *fmt, ...){ + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} +SYMBOL_WRAP_DECL(int, luaL_checkoption, lua_State *L, int narg, const char *def, const char *const lst[]){ + SYMBOL_WRAP_CALL(luaL_checkoption, L, narg, def, lst); +} +SYMBOL_WRAP_DECL(int, luaL_fileresult, lua_State *L, int stat, const char *fname){ + SYMBOL_WRAP_CALL(luaL_fileresult, L, stat, fname); +} +SYMBOL_WRAP_DECL(int, luaL_execresult, lua_State *L, int stat){ + SYMBOL_WRAP_CALL(luaL_execresult, L, stat); +} +SYMBOL_WRAP_DECL(int, luaL_ref, lua_State *L, int t){ + SYMBOL_WRAP_CALL(luaL_ref, L, t); +} +SYMBOL_WRAP_DECL(void, luaL_unref, lua_State *L, int t, int ref){ + SYMBOL_WRAP_CALL(luaL_unref, L, t, ref); +} +SYMBOL_WRAP_DECL(int, luaL_loadfilex, lua_State *L, const char *filename, const char *mode){ + SYMBOL_WRAP_CALL(luaL_loadfilex, L, filename, mode); +} +SYMBOL_WRAP_DECL(int, luaL_loadbufferx, lua_State *L, const char *buff, size_t sz, const char *name, const char *mode){ + SYMBOL_WRAP_CALL(luaL_loadbufferx, L, buff, sz, name, mode); +} +SYMBOL_WRAP_DECL(int, luaL_loadstring, lua_State *L, const char *s){ + SYMBOL_WRAP_CALL(luaL_loadstring, L, s); +} +SYMBOL_WRAP_DECL(lua_State *, luaL_newstate, void){ + return __luaL_newstate(); +} +SYMBOL_WRAP_DECL(int, luaL_len, lua_State *L, int idx){ + SYMBOL_WRAP_CALL(luaL_len, L, idx); +} +SYMBOL_WRAP_DECL(const char *, luaL_gsub, lua_State *L, const char *s, const char *p, const char *r){ + SYMBOL_WRAP_CALL(luaL_gsub, L, s, p, r); +} +SYMBOL_WRAP_DECL(void, luaL_setfuncs, lua_State *L, const luaL_Reg *l, int nup){ + SYMBOL_WRAP_CALL(luaL_setfuncs, L, l, nup); +} +SYMBOL_WRAP_DECL(int, luaL_getsubtable, lua_State *L, int idx, const char *fname){ + SYMBOL_WRAP_CALL(luaL_getsubtable, L, idx, fname); +} +SYMBOL_WRAP_DECL(void, luaL_traceback, lua_State *L, lua_State *L1, const char *msg, int level){ + SYMBOL_WRAP_CALL(luaL_traceback, L, L1, msg, level); +} +SYMBOL_WRAP_DECL(void, luaL_requiref, lua_State *L, const char *modname, lua_CFunction openf, int glb){ + SYMBOL_WRAP_CALL(luaL_requiref, L, modname, openf, glb); +} +SYMBOL_WRAP_DECL(void, luaL_buffinit, lua_State *L, luaL_Buffer *B){ + SYMBOL_WRAP_CALL(luaL_buffinit, L, B); +} +SYMBOL_WRAP_DECL(char *, luaL_prepbuffsize, luaL_Buffer *B, size_t sz){ + SYMBOL_WRAP_CALL(luaL_prepbuffsize, B, sz); +} +SYMBOL_WRAP_DECL(void, luaL_addlstring, luaL_Buffer *B, const char *s, size_t l){ + SYMBOL_WRAP_CALL(luaL_addlstring, B, s, l); +} +SYMBOL_WRAP_DECL(void, luaL_addstring, luaL_Buffer *B, const char *s){ + SYMBOL_WRAP_CALL(luaL_addstring, B, s); +} +SYMBOL_WRAP_DECL(void, luaL_addvalue, luaL_Buffer *B){ + SYMBOL_WRAP_CALL(luaL_addvalue, B); +} +SYMBOL_WRAP_DECL(void, luaL_pushresult, luaL_Buffer *B){ + SYMBOL_WRAP_CALL(luaL_pushresult, B); +} +SYMBOL_WRAP_DECL(void, luaL_pushresultsize, luaL_Buffer *B, size_t sz){ + SYMBOL_WRAP_CALL(luaL_pushresultsize, B, sz); +} +SYMBOL_WRAP_DECL(char *, luaL_buffinitsize, lua_State *L, luaL_Buffer *B, size_t sz){ + SYMBOL_WRAP_CALL(luaL_buffinitsize, L, B, sz); +} +SYMBOL_WRAP_DECL(void, luaL_openlibs, lua_State *L){ + SYMBOL_WRAP_CALL(luaL_openlibs, L); +} + +#define IMPORT_SYMBOL(name, ret, ...) \ + __##name = (\ + __##name = (ret (*) (__VA_ARGS__)) symbol(#name), \ + __##name == NULL ? &__lite_xl_fallback_##name : __##name\ + ) + +#define IMPORT_SYMBOL_OPT(name, ret, ...) \ + __##name = symbol(#name) + +static void lite_xl_plugin_init(void *XL) { + void* (*symbol)(const char *) = (void* (*) (const char *)) XL; + IMPORT_SYMBOL(lua_newstate, lua_State *, lua_Alloc f, void *ud); + IMPORT_SYMBOL(lua_close, void , lua_State *L); + IMPORT_SYMBOL(lua_newthread, lua_State *, lua_State *L); + IMPORT_SYMBOL(lua_atpanic, lua_CFunction , lua_State *L, lua_CFunction panicf); + IMPORT_SYMBOL(lua_version, const lua_Number *, lua_State *L); + IMPORT_SYMBOL(lua_absindex, int , lua_State *L, int idx); + IMPORT_SYMBOL(lua_gettop, int , lua_State *L); + IMPORT_SYMBOL(lua_settop, void , lua_State *L, int idx); + IMPORT_SYMBOL(lua_pushvalue, void , lua_State *L, int idx); + IMPORT_SYMBOL(lua_copy, void , lua_State *L, int fromidx, int toidx); + IMPORT_SYMBOL(lua_checkstack, int , lua_State *L, int sz); + IMPORT_SYMBOL(lua_xmove, void , lua_State *from, lua_State *to, int n); + IMPORT_SYMBOL(lua_isnumber, int , lua_State *L, int idx); + IMPORT_SYMBOL(lua_isstring, int , lua_State *L, int idx); + IMPORT_SYMBOL(lua_iscfunction, int , lua_State *L, int idx); + IMPORT_SYMBOL(lua_isuserdata, int , lua_State *L, int idx); + IMPORT_SYMBOL(lua_type, int , lua_State *L, int idx); + IMPORT_SYMBOL(lua_typename, const char *, lua_State *L, int tp); + IMPORT_SYMBOL(lua_tonumberx, lua_Number , lua_State *L, int idx, int *isnum); + IMPORT_SYMBOL(lua_tointegerx, lua_Integer , lua_State *L, int idx, int *isnum); + IMPORT_SYMBOL(lua_tounsignedx, lua_Unsigned , lua_State *L, int idx, int *isnum); + IMPORT_SYMBOL(lua_toboolean, int , lua_State *L, int idx); + IMPORT_SYMBOL(lua_tolstring, const char *, lua_State *L, int idx, size_t *len); + IMPORT_SYMBOL(lua_rawlen, size_t , lua_State *L, int idx); + IMPORT_SYMBOL(lua_tocfunction, lua_CFunction , lua_State *L, int idx); + IMPORT_SYMBOL(lua_touserdata, void *, lua_State *L, int idx); + IMPORT_SYMBOL(lua_tothread, lua_State *, lua_State *L, int idx); + IMPORT_SYMBOL(lua_topointer, const void *, lua_State *L, int idx); + IMPORT_SYMBOL(lua_arith, void , lua_State *L, int op); + IMPORT_SYMBOL(lua_rawequal, int , lua_State *L, int idx1, int idx2); + IMPORT_SYMBOL(lua_compare, int , lua_State *L, int idx1, int idx2, int op); + IMPORT_SYMBOL(lua_pushnil, void , lua_State *L); + IMPORT_SYMBOL(lua_pushnumber, void , lua_State *L, lua_Number n); + IMPORT_SYMBOL(lua_pushinteger, void , lua_State *L, lua_Integer n); + IMPORT_SYMBOL(lua_pushunsigned, void , lua_State *L, lua_Unsigned n); + IMPORT_SYMBOL(lua_pushlstring, const char *, lua_State *L, const char *s, size_t l); + IMPORT_SYMBOL(lua_pushstring, const char *, lua_State *L, const char *s); + IMPORT_SYMBOL(lua_pushvfstring, const char *, lua_State *L, const char *fmt, va_list argp); + IMPORT_SYMBOL(lua_pushfstring, const char *, lua_State *L, const char *fmt, ...); + IMPORT_SYMBOL(lua_pushcclosure, void , lua_State *L, lua_CFunction fn, int n); + IMPORT_SYMBOL(lua_pushboolean, void , lua_State *L, int b); + IMPORT_SYMBOL(lua_pushlightuserdata, void , lua_State *L, void *p); + IMPORT_SYMBOL(lua_pushthread, int , lua_State *L); + IMPORT_SYMBOL(lua_getglobal, void , lua_State *L, const char *var); + IMPORT_SYMBOL(lua_gettable, void , lua_State *L, int idx); + IMPORT_SYMBOL(lua_getfield, void , lua_State *L, int idx, const char *k); + IMPORT_SYMBOL(lua_rawget, void , lua_State *L, int idx); + IMPORT_SYMBOL(lua_rawgeti, void , lua_State *L, int idx, int n); + IMPORT_SYMBOL(lua_rawgetp, void , lua_State *L, int idx, const void *p); + IMPORT_SYMBOL(lua_createtable, void , lua_State *L, int narr, int nrec); + IMPORT_SYMBOL_OPT(lua_newuserdata, void *, lua_State *L, size_t sz); + IMPORT_SYMBOL(lua_newuserdatauv, void *, lua_State *L, size_t sz, int nuvalue); + IMPORT_SYMBOL(lua_getmetatable, int , lua_State *L, int objindex); + IMPORT_SYMBOL_OPT(lua_getuservalue, void , lua_State *L, int idx); + IMPORT_SYMBOL(lua_getiuservalue, void , lua_State *L, int idx, int n); + IMPORT_SYMBOL(lua_setglobal, void , lua_State *L, const char *var); + IMPORT_SYMBOL(lua_settable, void , lua_State *L, int idx); + IMPORT_SYMBOL(lua_setfield, void , lua_State *L, int idx, const char *k); + IMPORT_SYMBOL(lua_rawset, void , lua_State *L, int idx); + IMPORT_SYMBOL(lua_rawseti, void , lua_State *L, int idx, int n); + IMPORT_SYMBOL(lua_rawsetp, void , lua_State *L, int idx, const void *p); + IMPORT_SYMBOL(lua_setmetatable, int , lua_State *L, int objindex); + IMPORT_SYMBOL_OPT(lua_setuservalue, void , lua_State *L, int idx); + IMPORT_SYMBOL(lua_setiuservalue, void , lua_State *L, int idx, int n); + IMPORT_SYMBOL(lua_callk, void , lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k); + IMPORT_SYMBOL(lua_getctx, int , lua_State *L, int *ctx); + IMPORT_SYMBOL(lua_pcallk, int , lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k); + IMPORT_SYMBOL(lua_load, int , lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); + IMPORT_SYMBOL(lua_dump, int , lua_State *L, lua_Writer writer, void *data, int strip); + IMPORT_SYMBOL(lua_yieldk, int , lua_State *L, int nresults, int ctx, lua_CFunction k); + IMPORT_SYMBOL(lua_resume, int , lua_State *L, lua_State *from, int narg); + IMPORT_SYMBOL(lua_status, int , lua_State *L); + IMPORT_SYMBOL(lua_gc, int , lua_State *L, int what, int data); + IMPORT_SYMBOL(lua_error, int , lua_State *L); + IMPORT_SYMBOL(lua_next, int , lua_State *L, int idx); + IMPORT_SYMBOL(lua_concat, void , lua_State *L, int n); + IMPORT_SYMBOL(lua_len, void , lua_State *L, int idx); + IMPORT_SYMBOL(lua_getallocf, lua_Alloc , lua_State *L, void **ud); + IMPORT_SYMBOL(lua_setallocf, void , lua_State *L, lua_Alloc f, void *ud); + IMPORT_SYMBOL(lua_getstack, int , lua_State *L, int level, lua_Debug *ar); + IMPORT_SYMBOL(lua_getinfo, int , lua_State *L, const char *what, lua_Debug *ar); + IMPORT_SYMBOL(lua_getlocal, const char *, lua_State *L, const lua_Debug *ar, int n); + IMPORT_SYMBOL(lua_setlocal, const char *, lua_State *L, const lua_Debug *ar, int n); + IMPORT_SYMBOL(lua_getupvalue, const char *, lua_State *L, int funcindex, int n); + IMPORT_SYMBOL(lua_setupvalue, const char *, lua_State *L, int funcindex, int n); + IMPORT_SYMBOL(lua_upvalueid, void *, lua_State *L, int fidx, int n); + IMPORT_SYMBOL(lua_upvaluejoin, void , lua_State *L, int fidx1, int n1, int fidx2, int n2); + IMPORT_SYMBOL(lua_sethook, int , lua_State *L, lua_Hook func, int mask, int count); + IMPORT_SYMBOL(lua_gethook, lua_Hook , lua_State *L); + IMPORT_SYMBOL(lua_gethookmask, int , lua_State *L); + IMPORT_SYMBOL(lua_gethookcount, int , lua_State *L); + IMPORT_SYMBOL(luaL_checkversion_, void , lua_State *L, lua_Number ver); + IMPORT_SYMBOL(luaL_getmetafield, int , lua_State *L, int obj, const char *e); + IMPORT_SYMBOL(luaL_callmeta, int , lua_State *L, int obj, const char *e); + IMPORT_SYMBOL(luaL_tolstring, const char *, lua_State *L, int idx, size_t *len); + IMPORT_SYMBOL(luaL_argerror, int , lua_State *L, int numarg, const char *extramsg); + IMPORT_SYMBOL(luaL_checklstring, const char *, lua_State *L, int numArg, size_t *l); + IMPORT_SYMBOL(luaL_optlstring, const char *, lua_State *L, int numArg, const char *def, size_t *l); + IMPORT_SYMBOL(luaL_checknumber, lua_Number , lua_State *L, int numArg); + IMPORT_SYMBOL(luaL_optnumber, lua_Number , lua_State *L, int nArg, lua_Number def); + IMPORT_SYMBOL(luaL_checkinteger, lua_Integer , lua_State *L, int numArg); + IMPORT_SYMBOL(luaL_optinteger, lua_Integer , lua_State *L, int nArg, lua_Integer def); + IMPORT_SYMBOL(luaL_checkunsigned, lua_Unsigned , lua_State *L, int numArg); + IMPORT_SYMBOL(luaL_optunsigned, lua_Unsigned , lua_State *L, int numArg, lua_Unsigned def); + IMPORT_SYMBOL(luaL_checkstack, void , lua_State *L, int sz, const char *msg); + IMPORT_SYMBOL(luaL_checktype, void , lua_State *L, int narg, int t); + IMPORT_SYMBOL(luaL_checkany, void , lua_State *L, int narg); + IMPORT_SYMBOL(luaL_newmetatable, int , lua_State *L, const char *tname); + IMPORT_SYMBOL(luaL_setmetatable, void , lua_State *L, const char *tname); + IMPORT_SYMBOL(luaL_testudata, void *, lua_State *L, int ud, const char *tname); + IMPORT_SYMBOL(luaL_checkudata, void *, lua_State *L, int ud, const char *tname); + IMPORT_SYMBOL(luaL_where, void , lua_State *L, int lvl); + IMPORT_SYMBOL(luaL_error, int , lua_State *L, const char *fmt, ...); + IMPORT_SYMBOL(luaL_checkoption, int , lua_State *L, int narg, const char *def, const char *const lst[]); + IMPORT_SYMBOL(luaL_fileresult, int , lua_State *L, int stat, const char *fname); + IMPORT_SYMBOL(luaL_execresult, int , lua_State *L, int stat); + IMPORT_SYMBOL(luaL_ref, int , lua_State *L, int t); + IMPORT_SYMBOL(luaL_unref, void , lua_State *L, int t, int ref); + IMPORT_SYMBOL(luaL_loadfilex, int , lua_State *L, const char *filename, const char *mode); + IMPORT_SYMBOL(luaL_loadbufferx, int , lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); + IMPORT_SYMBOL(luaL_loadstring, int , lua_State *L, const char *s); + IMPORT_SYMBOL(luaL_newstate, lua_State *, void); + IMPORT_SYMBOL(luaL_len, int , lua_State *L, int idx); + IMPORT_SYMBOL(luaL_gsub, const char *, lua_State *L, const char *s, const char *p, const char *r); + IMPORT_SYMBOL(luaL_setfuncs, void , lua_State *L, const luaL_Reg *l, int nup); + IMPORT_SYMBOL(luaL_getsubtable, int , lua_State *L, int idx, const char *fname); + IMPORT_SYMBOL(luaL_traceback, void , lua_State *L, lua_State *L1, const char *msg, int level); + IMPORT_SYMBOL(luaL_requiref, void , lua_State *L, const char *modname, lua_CFunction openf, int glb); + IMPORT_SYMBOL(luaL_buffinit, void , lua_State *L, luaL_Buffer *B); + IMPORT_SYMBOL(luaL_prepbuffsize, char *, luaL_Buffer *B, size_t sz); + IMPORT_SYMBOL(luaL_addlstring, void , luaL_Buffer *B, const char *s, size_t l); + IMPORT_SYMBOL(luaL_addstring, void , luaL_Buffer *B, const char *s); + IMPORT_SYMBOL(luaL_addvalue, void , luaL_Buffer *B); + IMPORT_SYMBOL(luaL_pushresult, void , luaL_Buffer *B); + IMPORT_SYMBOL(luaL_pushresultsize, void , luaL_Buffer *B, size_t sz); + IMPORT_SYMBOL(luaL_buffinitsize, char *, lua_State *L, luaL_Buffer *B, size_t sz); + IMPORT_SYMBOL(luaL_openlibs, void, lua_State* L); +} + +#endif /* LITE_XL_PLUGIN_ENTRYPOINT */ + +#endif /* LITE_XL_PLUGIN_API */ From 5907118683e881489043731dda7a521971284446 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 19 Jan 2023 19:28:14 -0500 Subject: [PATCH 024/148] Added missing header declaration. --- resources/lite_xl_plugin_api.h | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/lite_xl_plugin_api.h b/resources/lite_xl_plugin_api.h index 257791ce..6d68e454 100644 --- a/resources/lite_xl_plugin_api.h +++ b/resources/lite_xl_plugin_api.h @@ -28,6 +28,7 @@ Go figure. #include #include // for BUFSIZ? this is kinda weird +#include #define SYMBOL_WRAP_DECL(ret, name, ...) \ ret name(__VA_ARGS__) From a951c3cd392304f3623cca36e317d8d2adc86b8b Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 22 Jan 2023 04:11:42 +0100 Subject: [PATCH 025/148] pass RenWindow by argument (#1321) * pass RenWindow to all renderer functions that need it * pass RenWindow to all rencache functions that need it --- src/api/renderer.c | 16 ++++++------ src/api/system.c | 6 ++--- src/main.c | 2 +- src/rencache.c | 22 ++++++++-------- src/rencache.h | 6 ++--- src/renderer.c | 64 +++++++++++++++++++++++----------------------- src/renderer.h | 27 +++++++++++-------- 7 files changed, 73 insertions(+), 70 deletions(-) diff --git a/src/api/renderer.c b/src/api/renderer.c index ae2c7ae0..d96fbe0a 100644 --- a/src/api/renderer.c +++ b/src/api/renderer.c @@ -90,7 +90,7 @@ static int f_font_load(lua_State *L) { return ret_code; RenFont** font = lua_newuserdata(L, sizeof(RenFont*)); - *font = ren_font_load(filename, size, antialiasing, hinting, style); + *font = ren_font_load(&window_renderer, filename, size, antialiasing, hinting, style); if (!*font) return luaL_error(L, "failed to load font"); luaL_setmetatable(L, API_TYPE_FONT); @@ -130,7 +130,7 @@ static int f_font_copy(lua_State *L) { } for (int i = 0; i < FONT_FALLBACK_MAX && fonts[i]; ++i) { RenFont** font = lua_newuserdata(L, sizeof(RenFont*)); - *font = ren_font_copy(fonts[i], size, antialiasing, hinting, style); + *font = ren_font_copy(&window_renderer, fonts[i], size, antialiasing, hinting, style); if (!*font) return luaL_error(L, "failed to copy font"); luaL_setmetatable(L, API_TYPE_FONT); @@ -198,7 +198,7 @@ static int f_font_get_width(lua_State *L) { size_t len; const char *text = luaL_checklstring(L, 2, &len); - lua_pushnumber(L, ren_font_group_get_width(fonts, text, len)); + lua_pushnumber(L, ren_font_group_get_width(&window_renderer, fonts, text, len)); return 1; } @@ -217,7 +217,7 @@ static int f_font_get_size(lua_State *L) { static int f_font_set_size(lua_State *L) { RenFont* fonts[FONT_FALLBACK_MAX]; font_retrieve(L, fonts, 1); float size = luaL_checknumber(L, 2); - ren_font_group_set_size(fonts, size); + ren_font_group_set_size(&window_renderer, fonts, size); return 0; } @@ -276,7 +276,7 @@ static int f_show_debug(lua_State *L) { static int f_get_size(lua_State *L) { int w, h; - ren_get_size(&w, &h); + ren_get_size(&window_renderer, &w, &h); lua_pushnumber(L, w); lua_pushnumber(L, h); return 2; @@ -284,13 +284,13 @@ static int f_get_size(lua_State *L) { static int f_begin_frame(UNUSED lua_State *L) { - rencache_begin_frame(); + rencache_begin_frame(&window_renderer); return 0; } static int f_end_frame(UNUSED lua_State *L) { - rencache_end_frame(); + rencache_end_frame(&window_renderer); // clear the font reference table lua_newtable(L); lua_rawseti(L, LUA_REGISTRYINDEX, RENDERER_FONT_REF); @@ -348,7 +348,7 @@ static int f_draw_text(lua_State *L) { float x = luaL_checknumber(L, 3); int y = luaL_checknumber(L, 4); RenColor color = checkcolor(L, 5, 255); - x = rencache_draw_text(fonts, text, len, x, y, color); + x = rencache_draw_text(&window_renderer, fonts, text, len, x, y, color); lua_pushnumber(L, x); return 1; } diff --git a/src/api/system.c b/src/api/system.c index 36d9c680..ad7cede8 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -37,8 +37,6 @@ #endif #endif -extern RenWindow window_renderer; - static const char* button_name(int button) { switch (button) { case SDL_BUTTON_LEFT : return "left"; @@ -188,7 +186,7 @@ top: case SDL_WINDOWEVENT: if (e.window.event == SDL_WINDOWEVENT_RESIZED) { - ren_resize_window(); + ren_resize_window(&window_renderer); lua_pushstring(L, "resized"); /* The size below will be in points. */ lua_pushinteger(L, e.window.data1); @@ -473,7 +471,7 @@ static int f_set_window_size(lua_State *L) { double y = luaL_checknumber(L, 4); SDL_SetWindowSize(window_renderer.window, w, h); SDL_SetWindowPosition(window_renderer.window, x, y); - ren_resize_window(); + ren_resize_window(&window_renderer); return 0; } diff --git a/src/main.c b/src/main.c index 3c08a643..32212df8 100644 --- a/src/main.c +++ b/src/main.c @@ -260,7 +260,7 @@ init_lua: } lua_close(L); - ren_free_window_resources(); + ren_free_window_resources(&window_renderer); return EXIT_SUCCESS; } diff --git a/src/rencache.c b/src/rencache.c index f0243f0b..5b930482 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -175,9 +175,9 @@ void rencache_draw_rect(RenRect rect, RenColor color) { } } -float rencache_draw_text(RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) +float rencache_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { - float width = ren_font_group_get_width(fonts, text, len); + float width = ren_font_group_get_width(window_renderer, fonts, text, len); RenRect rect = { x, y, (int)width, ren_font_group_get_height(fonts) }; if (rects_overlap(last_clip_rect, rect)) { int sz = len + 1; @@ -201,11 +201,11 @@ void rencache_invalidate(void) { } -void rencache_begin_frame() { +void rencache_begin_frame(RenWindow *window_renderer) { /* reset all cells if the screen width/height has changed */ int w, h; resize_issue = false; - ren_get_size(&w, &h); + ren_get_size(window_renderer, &w, &h); if (screen_rect.width != w || h != screen_rect.height) { screen_rect.width = w; screen_rect.height = h; @@ -244,7 +244,7 @@ static void push_rect(RenRect r, int *count) { } -void rencache_end_frame() { +void rencache_end_frame(RenWindow *window_renderer) { /* update cells from commands */ Command *cmd = NULL; RenRect cr = screen_rect; @@ -286,33 +286,33 @@ void rencache_end_frame() { for (int i = 0; i < rect_count; i++) { /* draw */ RenRect r = rect_buf[i]; - ren_set_clip_rect(r); + ren_set_clip_rect(window_renderer, r); cmd = NULL; while (next_command(&cmd)) { switch (cmd->type) { case SET_CLIP: - ren_set_clip_rect(intersect_rects(cmd->rect, r)); + ren_set_clip_rect(window_renderer, intersect_rects(cmd->rect, r)); break; case DRAW_RECT: - ren_draw_rect(cmd->rect, cmd->color); + ren_draw_rect(window_renderer, cmd->rect, cmd->color); break; case DRAW_TEXT: ren_font_group_set_tab_size(cmd->fonts, cmd->tab_size); - ren_draw_text(cmd->fonts, cmd->text, cmd->len, cmd->text_x, cmd->rect.y, cmd->color); + ren_draw_text(window_renderer, cmd->fonts, cmd->text, cmd->len, cmd->text_x, cmd->rect.y, cmd->color); break; } } if (show_debug) { RenColor color = { rand(), rand(), rand(), 50 }; - ren_draw_rect(r, color); + ren_draw_rect(window_renderer, r, color); } } /* update dirty rects */ if (rect_count > 0) { - ren_update_rects(rect_buf, rect_count); + ren_update_rects(window_renderer, rect_buf, rect_count); } /* swap cell buffer and reset */ diff --git a/src/rencache.h b/src/rencache.h index 49ca9135..925b50f0 100644 --- a/src/rencache.h +++ b/src/rencache.h @@ -8,9 +8,9 @@ void rencache_show_debug(bool enable); void rencache_set_clip_rect(RenRect rect); void rencache_draw_rect(RenRect rect, RenColor color); -float rencache_draw_text(RenFont **font, const char *text, size_t len, float x, int y, RenColor color); +float rencache_draw_text(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, float x, int y, RenColor color); void rencache_invalidate(void); -void rencache_begin_frame(); -void rencache_end_frame(); +void rencache_begin_frame(RenWindow *window_renderer); +void rencache_end_frame(RenWindow *window_renderer); #endif diff --git a/src/renderer.c b/src/renderer.c index 2932784a..53be1046 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -214,7 +214,7 @@ static void font_clear_glyph_cache(RenFont* font) { } } -RenFont* ren_font_load(const char* path, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, unsigned char style) { +RenFont* ren_font_load(RenWindow *window_renderer, const char* path, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, unsigned char style) { FT_Face face = NULL; #ifdef _WIN32 @@ -257,7 +257,7 @@ RenFont* ren_font_load(const char* path, float size, ERenFontAntialiasing antial #endif - const int surface_scale = renwin_surface_scale(&window_renderer); + const int surface_scale = renwin_surface_scale(window_renderer); if (FT_Set_Pixel_Sizes(face, 0, (int)(size*surface_scale))) goto failure; int len = strlen(path); @@ -300,12 +300,12 @@ failure: return NULL; } -RenFont* ren_font_copy(RenFont* font, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, int style) { +RenFont* ren_font_copy(RenWindow *window_renderer, RenFont* font, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, int style) { antialiasing = antialiasing == -1 ? font->antialiasing : antialiasing; hinting = hinting == -1 ? font->hinting : hinting; style = style == -1 ? font->style : style; - return ren_font_load(font->path, size, antialiasing, hinting, style); + return ren_font_load(window_renderer, font->path, size, antialiasing, hinting, style); } const char* ren_font_get_path(RenFont *font) { @@ -341,8 +341,8 @@ float ren_font_group_get_size(RenFont **fonts) { return fonts[0]->size; } -void ren_font_group_set_size(RenFont **fonts, float size) { - const int surface_scale = renwin_surface_scale(&window_renderer); +void ren_font_group_set_size(RenWindow *window_renderer, RenFont **fonts, float size) { + const int surface_scale = renwin_surface_scale(window_renderer); for (int i = 0; i < FONT_FALLBACK_MAX && fonts[i]; ++i) { font_clear_glyph_cache(fonts[i]); FT_Face face = fonts[i]->face; @@ -360,7 +360,7 @@ int ren_font_group_get_height(RenFont **fonts) { return fonts[0]->height; } -float ren_font_group_get_width(RenFont **fonts, const char *text, size_t len) { +float ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len) { float width = 0; const char* end = text + len; GlyphMetric* metric = NULL; GlyphSet* set = NULL; @@ -372,15 +372,15 @@ float ren_font_group_get_width(RenFont **fonts, const char *text, size_t len) { break; width += (!font || metric->xadvance) ? metric->xadvance : fonts[0]->space_advance; } - const int surface_scale = renwin_surface_scale(&window_renderer); + const int surface_scale = renwin_surface_scale(window_renderer); return width / surface_scale; } -float ren_draw_text(RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { - SDL_Surface *surface = renwin_get_surface(&window_renderer); - const RenRect clip = window_renderer.clip; +float ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { + SDL_Surface *surface = renwin_get_surface(window_renderer); + const RenRect clip = window_renderer->clip; - const int surface_scale = renwin_surface_scale(&window_renderer); + const int surface_scale = renwin_surface_scale(window_renderer); float pen_x = x * surface_scale; y *= surface_scale; int bytes_per_pixel = surface->format->BytesPerPixel; @@ -404,7 +404,7 @@ float ren_draw_text(RenFont **fonts, const char *text, size_t len, float x, int int end_x = (metric->x1 - metric->x0) + start_x; int glyph_end = metric->x1, glyph_start = metric->x0; if (!metric->loaded && codepoint > 0xFF) - ren_draw_rect((RenRect){ start_x + 1, y, font->space_advance - 1, ren_font_group_get_height(fonts) }, color); + ren_draw_rect(window_renderer, (RenRect){ start_x + 1, y, font->space_advance - 1, ren_font_group_get_height(fonts) }, color); if (set->surface && color.a > 0 && end_x >= clip.x && start_x < clip_end_x) { uint8_t* source_pixels = set->surface->pixels; for (int line = metric->y0; line < metric->y1; ++line) { @@ -455,9 +455,9 @@ float ren_draw_text(RenFont **fonts, const char *text, size_t len, float x, int else if(font != last || text == end) { float local_pen_x = text == end ? pen_x + adv : pen_x; if (underline) - ren_draw_rect((RenRect){last_pen_x, y / surface_scale + last->height - 1, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color); + ren_draw_rect(window_renderer, (RenRect){last_pen_x, y / surface_scale + last->height - 1, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color); if (strikethrough) - ren_draw_rect((RenRect){last_pen_x, y / surface_scale + last->height / 2, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color); + ren_draw_rect(window_renderer, (RenRect){last_pen_x, y / surface_scale + last->height / 2, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color); last = font; last_pen_x = pen_x; } @@ -476,10 +476,10 @@ static inline RenColor blend_pixel(RenColor dst, RenColor src) { return dst; } -void ren_draw_rect(RenRect rect, RenColor color) { +void ren_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color) { if (color.a == 0) { return; } - const int surface_scale = renwin_surface_scale(&window_renderer); + const int surface_scale = renwin_surface_scale(window_renderer); /* transforms coordinates in pixels. */ rect.x *= surface_scale; @@ -487,7 +487,7 @@ void ren_draw_rect(RenRect rect, RenColor color) { rect.width *= surface_scale; rect.height *= surface_scale; - const RenRect clip = window_renderer.clip; + const RenRect clip = window_renderer->clip; int x1 = rect.x < clip.x ? clip.x : rect.x; int y1 = rect.y < clip.y ? clip.y : rect.y; int x2 = rect.x + rect.width; @@ -495,7 +495,7 @@ void ren_draw_rect(RenRect rect, RenColor color) { x2 = x2 > clip.x + clip.width ? clip.x + clip.width : x2; y2 = y2 > clip.y + clip.height ? clip.y + clip.height : y2; - SDL_Surface *surface = renwin_get_surface(&window_renderer); + SDL_Surface *surface = renwin_get_surface(window_renderer); SDL_Rect dest_rect = { x1, y1, x2 - x1, y2 - y1 }; if (color.a == 0xff) { uint32_t translated = SDL_MapRGB(surface->format, color.r, color.g, color.b); @@ -508,16 +508,17 @@ void ren_draw_rect(RenRect rect, RenColor color) { } /*************** Window Management ****************/ -void ren_free_window_resources() { +void ren_free_window_resources(RenWindow *window_renderer) { extern uint8_t *command_buf; extern size_t command_buf_size; - renwin_free(&window_renderer); + renwin_free(window_renderer); SDL_FreeSurface(draw_rect_surface); free(command_buf); command_buf = NULL; command_buf_size = 0; } +// TODO remove global and return RenWindow* void ren_init(SDL_Window *win) { assert(win); int error = FT_Init_FreeType( &library ); @@ -533,30 +534,29 @@ void ren_init(SDL_Window *win) { } -void ren_resize_window() { - renwin_resize_surface(&window_renderer); +void ren_resize_window(RenWindow *window_renderer) { + renwin_resize_surface(window_renderer); } -void ren_update_rects(RenRect *rects, int count) { +void ren_update_rects(RenWindow *window_renderer, RenRect *rects, int count) { static bool initial_frame = true; if (initial_frame) { - renwin_show_window(&window_renderer); + renwin_show_window(window_renderer); initial_frame = false; } - renwin_update_rects(&window_renderer, rects, count); + renwin_update_rects(window_renderer, rects, count); } -void ren_set_clip_rect(RenRect rect) { - renwin_set_clip_rect(&window_renderer, rect); +void ren_set_clip_rect(RenWindow *window_renderer, RenRect rect) { + renwin_set_clip_rect(window_renderer, rect); } -void ren_get_size(int *x, int *y) { - RenWindow *ren = &window_renderer; - const int scale = renwin_surface_scale(ren); - SDL_Surface *surface = renwin_get_surface(ren); +void ren_get_size(RenWindow *window_renderer, int *x, int *y) { + const int scale = renwin_surface_scale(window_renderer); + SDL_Surface *surface = renwin_get_surface(window_renderer); *x = surface->w / scale; *y = surface->h / scale; } diff --git a/src/renderer.h b/src/renderer.h index c1b80f51..46e04341 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -11,6 +11,7 @@ #define UNUSED #endif + #define FONT_FALLBACK_MAX 10 typedef struct RenFont RenFont; typedef enum { FONT_HINTING_NONE, FONT_HINTING_SLIGHT, FONT_HINTING_FULL } ERenFontHinting; @@ -19,26 +20,30 @@ typedef enum { FONT_STYLE_BOLD = 1, FONT_STYLE_ITALIC = 2, FONT_STYLE_UNDERLINE typedef struct { uint8_t b, g, r, a; } RenColor; typedef struct { int x, y, width, height; } RenRect; -RenFont* ren_font_load(const char *filename, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, unsigned char style); -RenFont* ren_font_copy(RenFont* font, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, int style); +struct RenWindow; +typedef struct RenWindow RenWindow; +extern RenWindow window_renderer; + +RenFont* ren_font_load(RenWindow *window_renderer, const char *filename, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, unsigned char style); +RenFont* ren_font_copy(RenWindow *window_renderer, RenFont* font, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, int style); const char* ren_font_get_path(RenFont *font); void ren_font_free(RenFont *font); int ren_font_group_get_tab_size(RenFont **font); int ren_font_group_get_height(RenFont **font); float ren_font_group_get_size(RenFont **font); -void ren_font_group_set_size(RenFont **font, float size); +void ren_font_group_set_size(RenWindow *window_renderer, RenFont **font, float size); void ren_font_group_set_tab_size(RenFont **font, int n); -float ren_font_group_get_width(RenFont **font, const char *text, size_t len); -float ren_draw_text(RenFont **font, const char *text, size_t len, float x, int y, RenColor color); +float ren_font_group_get_width(RenWindow *window_renderer, RenFont **font, const char *text, size_t len); +float ren_draw_text(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, float x, int y, RenColor color); -void ren_draw_rect(RenRect rect, RenColor color); +void ren_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color); void ren_init(SDL_Window *win); -void ren_resize_window(); -void ren_update_rects(RenRect *rects, int count); -void ren_set_clip_rect(RenRect rect); -void ren_get_size(int *x, int *y); /* Reports the size in points. */ -void ren_free_window_resources(); +void ren_resize_window(RenWindow *window_renderer); +void ren_update_rects(RenWindow *window_renderer, RenRect *rects, int count); +void ren_set_clip_rect(RenWindow *window_renderer, RenRect rect); +void ren_get_size(RenWindow *window_renderer, int *x, int *y); /* Reports the size in points. */ +void ren_free_window_resources(RenWindow *window_renderer); #endif From 03d11c869dd044a7425ccd727046a6000e835143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jefferson=20Gonz=C3=A1lez?= Date: Tue, 24 Jan 2023 15:25:56 -0400 Subject: [PATCH 026/148] ci: fix msys build now requiring ca-certificates (#1348) Thanks to Guldoman who discovered the cause for meson failing to validate SSL certificates which turned out to be MSYS now requiring ca-certificates package installed for the different architectures. --- scripts/install-dependencies.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/install-dependencies.sh b/scripts/install-dependencies.sh index d817097d..1290cfcc 100644 --- a/scripts/install-dependencies.sh +++ b/scripts/install-dependencies.sh @@ -63,10 +63,10 @@ main() { elif [[ "$OSTYPE" == "msys" ]]; then if [[ $lhelper == true ]]; then pacman --noconfirm -S \ - ${MINGW_PACKAGE_PREFIX}-{gcc,meson,ninja,ntldd,pkg-config,mesa} unzip + ${MINGW_PACKAGE_PREFIX}-{ca-certificates,gcc,meson,ninja,ntldd,pkg-config,mesa} unzip else pacman --noconfirm -S \ - ${MINGW_PACKAGE_PREFIX}-{gcc,meson,ninja,ntldd,pkg-config,mesa,freetype,pcre2,SDL2} unzip + ${MINGW_PACKAGE_PREFIX}-{ca-certificates,gcc,meson,ninja,ntldd,pkg-config,mesa,freetype,pcre2,SDL2} unzip fi fi } From b8eb6865a6c4b07094238a461c7061d377209753 Mon Sep 17 00:00:00 2001 From: jgmdev Date: Wed, 25 Jan 2023 17:28:34 -0400 Subject: [PATCH 027/148] gh workflow: fix path to macOS arm64 cross file --- .github/workflows/release.yml | 2 +- scripts/build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a8d97e54..ea0e1848 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -93,7 +93,7 @@ jobs: LiteXL-${{ env.INSTALL_REF }}-addons-x86_64.AppImage build_macos: - name: macOS (x86_64) + name: macOS needs: release runs-on: macos-11 strategy: diff --git a/scripts/build.sh b/scripts/build.sh index 5812bd8b..82eb95f0 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -111,7 +111,7 @@ main() { if [[ $platform == "macos" ]]; then macos_version_min=10.11 if [[ $CROSS_ARCH == "arm64" ]]; then - cross_file="--cross-file resources/macos/macos_arm64.conf" + cross_file="--cross-file resources/cross/macos_arm64.txt" macos_version_min=11.0 fi export MACOSX_DEPLOYMENT_TARGET=$macos_version_min From 017711b36911b7ab498fd8106b93582d2dbda298 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 30 Jan 2023 11:10:11 -0500 Subject: [PATCH 028/148] Getting rid of annoying forward slash on windows. (#1345) --- data/core/init.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index 89ac7ec4..4ff89b8c 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -18,13 +18,13 @@ local Doc local core = {} local function load_session() - local ok, t = pcall(dofile, USERDIR .. "/session.lua") + local ok, t = pcall(dofile, USERDIR .. PATHSEP .. "session.lua") return ok and t or {} end local function save_session() - local fp = io.open(USERDIR .. "/session.lua", "w") + local fp = io.open(USERDIR .. PATHSEP .. "session.lua", "w") if fp then fp:write("return {recents=", common.serialize(core.recent_projects), ", window=", common.serialize(table.pack(system.get_window_size())), @@ -607,7 +607,7 @@ function core.load_user_directory() if not stat_dir then create_user_directory() end - local init_filename = USERDIR .. "/init.lua" + local init_filename = USERDIR .. PATHSEP .. "init.lua" local stat_file = system.get_file_info(init_filename) if not stat_file then write_user_init_file(init_filename) @@ -924,7 +924,7 @@ end local function get_plugin_details(filename) local info = system.get_file_info(filename) if info ~= nil and info.type == "dir" then - filename = filename .. "/init.lua" + filename = filename .. PATHSEP .. "init.lua" info = system.get_file_info(filename) end if not info or not filename:match("%.lua$") then return false end @@ -963,7 +963,7 @@ function core.load_plugins() } local files, ordered = {}, {} for _, root_dir in ipairs {DATADIR, USERDIR} do - local plugin_dir = root_dir .. "/plugins" + local plugin_dir = root_dir .. PATHSEP .. "plugins" for _, filename in ipairs(system.list_dir(plugin_dir) or {}) do if not files[filename] then table.insert( @@ -978,7 +978,7 @@ function core.load_plugins() for _, plugin in ipairs(ordered) do local dir = files[plugin.file] local name = plugin.file:match("(.-)%.lua$") or plugin.file - local is_lua_file, details = get_plugin_details(dir .. '/' .. plugin.file) + local is_lua_file, details = get_plugin_details(dir .. PATHSEP .. plugin.file) plugin.valid = is_lua_file plugin.name = name @@ -1423,7 +1423,7 @@ end function core.on_error(err) -- write error to file - local fp = io.open(USERDIR .. "/error.txt", "wb") + local fp = io.open(USERDIR .. PATHSEP .. "error.txt", "wb") fp:write("Error: " .. tostring(err) .. "\n") fp:write(debug.traceback("", 4) .. "\n") fp:close() From 218ba3ebac5e292f808d1ae2d4415321a7d4faae Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sat, 19 Aug 2023 12:36:39 +0800 Subject: [PATCH 029/148] Context menu fixes and keyboard navigation (#1338) * fix Doc contextmenu not registering commands if scale plugin is not found * fix TreeView contextmenu commands not working if the mouse hovers DocView * add keyboard navigation to TreeView contextmenu * fix incorrect contextmenu predicate Co-Authored-By: vqn <85911372+vqns@users.noreply.github.com> --- data/plugins/contextmenu.lua | 31 +++++++++++++++++----------- data/plugins/treeview.lua | 39 ++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/data/plugins/contextmenu.lua b/data/plugins/contextmenu.lua index db6d28db..26afbb57 100644 --- a/data/plugins/contextmenu.lua +++ b/data/plugins/contextmenu.lua @@ -4,6 +4,7 @@ local command = require "core.command" local keymap = require "core.keymap" local ContextMenu = require "core.contextmenu" local RootView = require "core.rootview" +local config = require "core.config" local menu = ContextMenu() local on_view_mouse_pressed = RootView.on_view_mouse_pressed @@ -61,18 +62,24 @@ keymap.add { ["up"] = "context:focus-previous" } keymap.add { ["down"] = "context:focus-next" } keymap.add { ["escape"] = "context:hide" } -if require("plugins.scale") then - menu:register("core.docview", { - { text = "Cut", command = "doc:cut" }, - { text = "Copy", command = "doc:copy" }, - { text = "Paste", command = "doc:paste" }, - { text = "Font +", command = "scale:increase" }, - { text = "Font -", command = "scale:decrease" }, - { text = "Font Reset", command = "scale:reset" }, - ContextMenu.DIVIDER, - { text = "Find", command = "find-replace:find" }, - { text = "Replace", command = "find-replace:replace" } - }) + +local cmds = { + { text = "Cut", command = "doc:cut" }, + { text = "Copy", command = "doc:copy" }, + { text = "Paste", command = "doc:paste" }, + ContextMenu.DIVIDER, + { text = "Find", command = "find-replace:find" }, + { text = "Replace", command = "find-replace:replace" } +} + +if config.plugins.scale ~= false and require("plugins.scale") then + table.move(cmds, 4, 6, 7) + cmds[4] = { text = "Font +", command = "scale:increase" } + cmds[5] = { text = "Font -", command = "scale:decrease" } + cmds[6] = { text = "Font Reset", command = "scale:reset" } end +menu:register("core.docview", cmds) + + return menu diff --git a/data/plugins/treeview.lua b/data/plugins/treeview.lua index dee02846..cf5f6013 100644 --- a/data/plugins/treeview.lua +++ b/data/plugins/treeview.lua @@ -518,15 +518,19 @@ local function is_primary_project_folder(path) return core.project_dir == path end -menu:register(function() return view.hovered_item end, { + +local function treeitem() return view.hovered_item or view.selected_item end + + +menu:register(function() return core.active_view:is(TreeView) and treeitem() end, { { text = "Open in System", command = "treeview:open-in-system" }, ContextMenu.DIVIDER }) menu:register( function() - return view.hovered_item - and not is_project_folder(view.hovered_item.abs_filename) + local item = treeitem() + return core.active_view:is(TreeView) and item and not is_project_folder(item.abs_filename) end, { { text = "Rename", command = "treeview:rename" }, @@ -536,7 +540,8 @@ menu:register( menu:register( function() - return view.hovered_item and view.hovered_item.type == "dir" + local item = treeitem() + return core.active_view:is(TreeView) and item and item.type == "dir" end, { { text = "New File", command = "treeview:new-file" }, @@ -546,9 +551,10 @@ menu:register( menu:register( function() - return view.hovered_item - and not is_primary_project_folder(view.hovered_item.abs_filename) - and is_project_folder(view.hovered_item.abs_filename) + local item = treeitem() + return core.active_view:is(TreeView) and item + and not is_primary_project_folder(item.abs_filename) + and is_project_folder(item.abs_filename) end, { { text = "Remove directory", command = "treeview:remove-project-directory" }, @@ -589,7 +595,10 @@ command.add(nil, { end }) -command.add(TreeView, { +command.add( + function() + return not menu.show_context_menu and core.active_view:extends(TreeView), TreeView + end, { ["treeview:next"] = function() local item, _, item_y = view:get_next(view.selected_item) view:set_selection(item, item_y) @@ -660,19 +669,10 @@ command.add(TreeView, { }) -local function treeitem() return view.hovered_item or view.selected_item end - - command.add( function() local item = treeitem() - return item ~= nil - and ( - core.active_view == view or core.active_view == menu - or (view.toolbar and core.active_view == view.toolbar) - -- sometimes the context menu is shown on top of statusbar - or core.active_view == core.status_view - ), item + return item ~= nil and (core.active_view == view or menu.show_context_menu), item end, { ["treeview:delete"] = function(item) local filename = item.abs_filename @@ -800,7 +800,8 @@ command.add( local projectsearch = pcall(require, "plugins.projectsearch") if projectsearch then menu:register(function() - return view.hovered_item and view.hovered_item.type == "dir" + local item = treeitem() + return item and item.type == "dir" end, { { text = "Find in directory", command = "treeview:search-in-directory" } }) From b95fdfcf5fcc78cd0838ca2f708d6f0c6f133897 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Wed, 1 Feb 2023 06:26:15 +0800 Subject: [PATCH 030/148] fix: exec() error not returned to parent (#1363) * fix: exec() error not returned to parent * chore: remove accidental lua.h inclusion --- src/api/process.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/api/process.c b/src/api/process.c index 60efe5f9..081e6ab6 100644 --- a/src/api/process.c +++ b/src/api/process.c @@ -293,6 +293,7 @@ static int process_start(lua_State* L) { CloseHandle(self->process_information.hProcess); CloseHandle(self->process_information.hThread); #else + int control_pipe[2] = { 0 }; for (int i = 0; i < 3; ++i) { // Make only the parents fd's non-blocking. Children should block. if (pipe(self->child_pipes[i]) || fcntl(self->child_pipes[i][i == STDIN_FD ? 1 : 0], F_SETFL, O_NONBLOCK) == -1) { lua_pushfstring(L, "Error creating pipes: %s", strerror(errno)); @@ -300,12 +301,25 @@ static int process_start(lua_State* L) { goto cleanup; } } + // create a pipe to get the exit code of exec() + if (pipe(control_pipe) == -1) { + lua_pushfstring(L, "Error creating control pipe: %s", strerror(errno)); + retval = -1; + goto cleanup; + } + if (fcntl(control_pipe[1], F_SETFD, FD_CLOEXEC) == -1) { + lua_pushfstring(L, "Error setting FD_CLOEXEC: %s", strerror(errno)); + retval = -1; + goto cleanup; + } + self->pid = (long)fork(); if (self->pid < 0) { lua_pushfstring(L, "Error running fork: %s.", strerror(errno)); retval = -1; goto cleanup; } else if (!self->pid) { + // child process if (!detach) setpgid(0,0); for (int stream = 0; stream < 3; ++stream) { @@ -320,12 +334,39 @@ static int process_start(lua_State* L) { for (set = 0; set < env_len && setenv(env_names[set], env_values[set], 1) == 0; ++set); if (set == env_len && (!detach || setsid() != -1) && (!cwd || chdir(cwd) != -1)) execvp(cmd[0], (char** const)cmd); - const char* msg = strerror(errno); - size_t result = write(STDERR_FD, msg, strlen(msg)+1); - _exit(result == strlen(msg)+1 ? -1 : -2); + write(control_pipe[1], &errno, sizeof(errno)); + _exit(-1); } + // close our write side so we can read from child + close(control_pipe[1]); + control_pipe[1] = 0; + + // wait for child process to respond + int sz, process_rc; + while ((sz = read(control_pipe[0], &process_rc, sizeof(int))) == -1) { + if (errno == EPIPE) break; + if (errno != EINTR) { + lua_pushfstring(L, "Error getting child process status: %s", strerror(errno)); + retval = -1; + goto cleanup; + } + } + + if (sz) { + // read something from pipe; exec failed + int status; + waitpid(self->pid, &status, 0); + lua_pushfstring(L, "Error creating child process: %s", strerror(process_rc)); + retval = -1; + goto cleanup; + } + #endif cleanup: + #ifndef _WIN32 + if (control_pipe[0]) close(control_pipe[0]); + if (control_pipe[1]) close(control_pipe[1]); + #endif for (size_t i = 0; i < env_len; ++i) { free((char*)env_names[i]); free((char*)env_values[i]); From 6925c06599b1b18f427db27f119b461826ffff6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jefferson=20Gonz=C3=A1lez?= Date: Mon, 6 Feb 2023 13:32:44 -0400 Subject: [PATCH 031/148] Improved plugins config table handling (#1356) * Warns user if trying to disable a plugin that is already enabled when doing `config.plugins.plugin_name = false` and also prevents replacing the current plugin config table with the false value to mitigate runtime issues. * Uses a merge strategy by default when assigning a table to a plugin config to prevent a user from removing a plugin default config values as experienced and explained on this issue lite-xl-plugins#158 * This change is basically backwards compatible, but will require a change on the settings ui plugin on how it checks for already enabled plugins, since rawget will no longer be a working hack or workaround for this. * As suggested by Adam dropped loaded key and switched to package.loaded --- data/core/config.lua | 46 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/data/core/config.lua b/data/core/config.lua index ecdcfdb5..fc5da98a 100644 --- a/data/core/config.lua +++ b/data/core/config.lua @@ -1,3 +1,5 @@ +local common = require "core.common" + local config = {} config.fps = 60 @@ -55,13 +57,47 @@ config.max_clicks = 3 -- set as true to be able to test non supported plugins config.skip_plugins_version = false +-- holds the plugins real config table +local plugins_config = {} + +-- virtual representation of plugins config table config.plugins = {} --- Allow you to set plugin configs even if we haven't seen the plugin before. + +-- allows virtual access to the plugins config table setmetatable(config.plugins, { - __index = function(t, k) - local v = rawget(t, k) - if v == true or v == nil then v = {} rawset(t, k, v) end - return v + __index = function(_, k) + if not plugins_config[k] then + plugins_config[k] = { enabled = true, config = {} } + end + if plugins_config[k].enabled ~= false then + return plugins_config[k].config + end + return false + end, + __newindex = function(_, k, v) + if not plugins_config[k] then + plugins_config[k] = { enabled = nil, config = {} } + end + if v == false and package.loaded["plugins."..k] then + local core = require "core" + core.warn("[%s] is already enabled, restart the editor for the change to take effect", k) + return + elseif plugins_config[k].enabled == false and v ~= false then + plugins_config[k].enabled = true + end + if v == false then + plugins_config[k].enabled = false + elseif type(v) == "table" then + plugins_config[k].enabled = true + plugins_config[k].config = common.merge(plugins_config[k].config, v) + end + end, + __pairs = function() + return coroutine.wrap(function() + for name, status in pairs(plugins_config) do + coroutine.yield(name, status.config) + end + end) end }) From 70ed1716121e841212493987588fce090a523bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jefferson=20Gonz=C3=A1lez?= Date: Mon, 6 Feb 2023 13:38:00 -0400 Subject: [PATCH 032/148] NagView: properly rescale on scale change (#1379) * drop font option since style.font is always used --- data/core/commands/doc.lua | 4 ++-- data/core/init.lua | 8 ++++---- data/core/nagview.lua | 14 ++++++++++++-- data/plugins/autoreload.lua | 4 ++-- data/plugins/treeview.lua | 4 ++-- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index 6d32219a..ebaf698c 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -44,8 +44,8 @@ local function save(filename) else core.error(err) core.nag_view:show("Saving failed", string.format("Could not save \"%s\" do you want to save to another location?", doc().filename), { - { font = style.font, text = "No", default_no = true }, - { font = style.font, text = "Yes" , default_yes = true } + { text = "No", default_no = true }, + { text = "Yes", default_yes = true } }, function(item) if item.text == "Yes" then core.add_thread(function() diff --git a/data/core/init.lua b/data/core/init.lua index 4ff89b8c..8a1785c5 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -818,8 +818,8 @@ function core.init() if #plugins_refuse_list.userdir.plugins > 0 or #plugins_refuse_list.datadir.plugins > 0 then local opt = { - { font = style.font, text = "Exit", default_no = true }, - { font = style.font, text = "Continue" , default_yes = true } + { text = "Exit", default_no = true }, + { text = "Continue", default_yes = true } } local msg = {} for _, entry in pairs(plugins_refuse_list) do @@ -860,8 +860,8 @@ function core.confirm_close_docs(docs, close_fn, ...) end local args = {...} local opt = { - { font = style.font, text = "Yes", default_yes = true }, - { font = style.font, text = "No" , default_no = true } + { text = "Yes", default_yes = true }, + { text = "No", default_no = true } } core.nag_view:show("Unsaved Changes", text, opt, function(item) if item.text == "Yes" then close_fn(table.unpack(args)) end diff --git a/data/core/nagview.lua b/data/core/nagview.lua index 9c373f58..b66da75c 100644 --- a/data/core/nagview.lua +++ b/data/core/nagview.lua @@ -91,7 +91,7 @@ function NagView:each_option() for i = #self.options, 1, -1 do opt = self.options[i] - bw = opt.font:get_width(opt.text) + 2 * BORDER_WIDTH + style.padding.x + bw = style.font:get_width(opt.text) + 2 * BORDER_WIDTH + style.padding.x ox = ox - bw - style.padding.x coroutine.yield(i, opt, ox,oy,bw,bh) @@ -230,7 +230,7 @@ local function draw_nagview_message(self) renderer.draw_rect(lx,ly,uw,UNDERLINE_WIDTH, style.nagbar_text) end - common.draw_text(opt.font, style.nagbar_text, opt.text, "center", fx,fy,fw,fh) + common.draw_text(style.font, style.nagbar_text, opt.text, "center", fx,fy,fw,fh) end self:draw_scrollbar() @@ -245,6 +245,16 @@ function NagView:draw() core.root_view:defer_draw(draw_nagview_message, self) end +function NagView:on_scale_change(new_scale, old_scale) + BORDER_WIDTH = common.round(1 * new_scale) + UNDERLINE_WIDTH = common.round(2 * new_scale) + UNDERLINE_MARGIN = common.round(1 * new_scale) + self.target_height = math.max( + self:get_message_height(), + self:get_buttons_height() + ) +end + function NagView:get_message_height() local h = 0 for str in string.gmatch(self.message, "(.-)\n") do diff --git a/data/plugins/autoreload.lua b/data/plugins/autoreload.lua index cde1c085..8286d62f 100644 --- a/data/plugins/autoreload.lua +++ b/data/plugins/autoreload.lua @@ -46,8 +46,8 @@ end local function check_prompt_reload(doc) if doc and doc.deferred_reload then core.nag_view:show("File Changed", doc.filename .. " has changed. Reload this file?", { - { font = style.font, text = "Yes", default_yes = true }, - { font = style.font, text = "No" , default_no = true } + { text = "Yes", default_yes = true }, + { text = "No", default_no = true } }, function(item) if item.text == "Yes" then reload_doc(doc) end doc.deferred_reload = false diff --git a/data/plugins/treeview.lua b/data/plugins/treeview.lua index cf5f6013..e529cae1 100644 --- a/data/plugins/treeview.lua +++ b/data/plugins/treeview.lua @@ -685,8 +685,8 @@ command.add( local file_type = file_info.type == "dir" and "Directory" or "File" -- Ask before deleting local opt = { - { font = style.font, text = "Yes", default_yes = true }, - { font = style.font, text = "No" , default_no = true } + { text = "Yes", default_yes = true }, + { text = "No", default_no = true } } core.nag_view:show( string.format("Delete %s", file_type), From 24491bc3fdfb80c395298cfd70ce899e0aee1d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jefferson=20Gonz=C3=A1lez?= Date: Mon, 6 Feb 2023 13:40:12 -0400 Subject: [PATCH 033/148] plugins scale: also rescale style.expanded_scrollbar_size (#1380) --- data/plugins/scale.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/data/plugins/scale.lua b/data/plugins/scale.lua index 0c9c8657..7c9e6d4c 100644 --- a/data/plugins/scale.lua +++ b/data/plugins/scale.lua @@ -39,12 +39,13 @@ local function set_scale(scale) if config.plugins.scale.mode == "ui" then SCALE = scale - style.padding.x = style.padding.x * s - style.padding.y = style.padding.y * s - style.divider_size = style.divider_size * s - style.scrollbar_size = style.scrollbar_size * s - style.caret_width = style.caret_width * s - style.tab_width = style.tab_width * s + style.padding.x = style.padding.x * s + style.padding.y = style.padding.y * s + style.divider_size = style.divider_size * s + style.scrollbar_size = style.scrollbar_size * s + style.expanded_scrollbar_size = style.expanded_scrollbar_size * s + style.caret_width = style.caret_width * s + style.tab_width = style.tab_width * s for _, name in ipairs {"font", "big_font", "icon_font", "icon_big_font", "code_font"} do style[name]:set_size(s * style[name]:get_size()) From b0e524dd153d0a84058bfe04a63e0ee4157c2def Mon Sep 17 00:00:00 2001 From: Guldoman Date: Mon, 6 Feb 2023 19:03:29 +0100 Subject: [PATCH 034/148] Improve `DocView:get_visible_line_range` precision (#1382) --- data/core/docview.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/core/docview.lua b/data/core/docview.lua index bf222738..1c3ff6de 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -160,8 +160,8 @@ end function DocView:get_visible_line_range() local x, y, x2, y2 = self:get_content_bounds() local lh = self:get_line_height() - local minline = math.max(1, math.floor(y / lh)) - local maxline = math.min(#self.doc.lines, math.floor(y2 / lh) + 1) + local minline = math.max(1, math.floor((y - style.padding.y) / lh) + 1) + local maxline = math.min(#self.doc.lines, math.floor((y2 - style.padding.y) / lh) + 1) return minline, maxline end From c8f033ec8b8dd605af56c2b00bafaffff9262223 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 9 Feb 2023 11:55:47 -0500 Subject: [PATCH 035/148] Fixed up some post 5.1/jit Symbols (#1385) * Updated k functions to have appropriate method signatures for 5.3 and up. * Fixed up some inconsistent signatures that I forgot. --- resources/lite_xl_plugin_api.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/resources/lite_xl_plugin_api.h b/resources/lite_xl_plugin_api.h index 6d68e454..8bf74054 100644 --- a/resources/lite_xl_plugin_api.h +++ b/resources/lite_xl_plugin_api.h @@ -205,6 +205,7 @@ Go figure. #define luai_numisnan(L,a) (!luai_numeq((a), (a))) #endif #define LUA_INTEGER ptrdiff_t +#define LUA_KCONTEXT ptrdiff_t #define LUA_UNSIGNED unsigned LUA_INT32 #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) #if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) @@ -235,10 +236,12 @@ typedef int (*lua_CFunction) (lua_State *L); typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); +typedef LUA_KCONTEXT lua_KContext; typedef LUA_NUMBER lua_Number; typedef LUA_INTEGER lua_Integer; typedef LUA_UNSIGNED lua_Unsigned; typedef struct lua_Debug lua_Debug; +typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); struct lua_Debug { int event; @@ -321,12 +324,12 @@ SYMBOL_DECLARE(void, lua_rawsetp, lua_State *L, int idx, SYMBOL_DECLARE(int, lua_setmetatable, lua_State *L, int objindex) SYMBOL_DECLARE(void, lua_setuservalue, lua_State *L, int idx) SYMBOL_DECLARE(void, lua_setiuservalue, lua_State *L, int idx, int n) -SYMBOL_DECLARE(void, lua_callk, lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k) +SYMBOL_DECLARE(void, lua_callk, lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k) SYMBOL_DECLARE(int, lua_getctx, lua_State *L, int *ctx) -SYMBOL_DECLARE(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k) +SYMBOL_DECLARE(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k) SYMBOL_DECLARE(int, lua_load, lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode) SYMBOL_DECLARE(int, lua_dump, lua_State *L, lua_Writer writer, void *data, int strip) -SYMBOL_DECLARE(int, lua_yieldk, lua_State *L, int nresults, int ctx, lua_CFunction k) +SYMBOL_DECLARE(int, lua_yieldk, lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k) SYMBOL_DECLARE(int, lua_resume, lua_State *L, lua_State *from, int narg) SYMBOL_DECLARE(int, lua_status, lua_State *L) SYMBOL_DECLARE(int, lua_gc, lua_State *L, int what, int data) @@ -740,13 +743,13 @@ SYMBOL_WRAP_DECL(void, lua_setuservalue, lua_State *L, int idx){ SYMBOL_WRAP_DECL(void, lua_setiuservalue, lua_State *L, int idx, int n){ SYMBOL_WRAP_CALL(lua_setiuservalue, L, idx, n); } -SYMBOL_WRAP_DECL(void, lua_callk, lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k){ +SYMBOL_WRAP_DECL(void, lua_callk, lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k){ SYMBOL_WRAP_CALL(lua_callk, L, nargs, nresults, ctx, k); } SYMBOL_WRAP_DECL(int, lua_getctx, lua_State *L, int *ctx){ SYMBOL_WRAP_CALL(lua_getctx, L, ctx); } -SYMBOL_WRAP_DECL(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k){ +SYMBOL_WRAP_DECL(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k){ SYMBOL_WRAP_CALL(lua_pcallk, L, nargs, nresults, errfunc, ctx, k); } SYMBOL_WRAP_DECL(int, lua_load, lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode){ @@ -755,7 +758,7 @@ SYMBOL_WRAP_DECL(int, lua_load, lua_State *L, lua_Reader reader, void *dt, const SYMBOL_WRAP_DECL(int, lua_dump, lua_State *L, lua_Writer writer, void *data, int strip){ SYMBOL_WRAP_CALL(lua_dump, L, writer, data, strip); } -SYMBOL_WRAP_DECL(int, lua_yieldk, lua_State *L, int nresults, int ctx, lua_CFunction k){ +SYMBOL_WRAP_DECL(int, lua_yieldk, lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k){ SYMBOL_WRAP_CALL(lua_yieldk, L, nresults, ctx, k); } SYMBOL_WRAP_DECL(int, lua_resume, lua_State *L, lua_State *from, int narg){ @@ -1041,12 +1044,12 @@ static void lite_xl_plugin_init(void *XL) { IMPORT_SYMBOL(lua_setmetatable, int , lua_State *L, int objindex); IMPORT_SYMBOL_OPT(lua_setuservalue, void , lua_State *L, int idx); IMPORT_SYMBOL(lua_setiuservalue, void , lua_State *L, int idx, int n); - IMPORT_SYMBOL(lua_callk, void , lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k); + IMPORT_SYMBOL(lua_callk, void , lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k); IMPORT_SYMBOL(lua_getctx, int , lua_State *L, int *ctx); - IMPORT_SYMBOL(lua_pcallk, int , lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k); + IMPORT_SYMBOL(lua_pcallk, int , lua_State *L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k); IMPORT_SYMBOL(lua_load, int , lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); IMPORT_SYMBOL(lua_dump, int , lua_State *L, lua_Writer writer, void *data, int strip); - IMPORT_SYMBOL(lua_yieldk, int , lua_State *L, int nresults, int ctx, lua_CFunction k); + IMPORT_SYMBOL(lua_yieldk, int , lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k); IMPORT_SYMBOL(lua_resume, int , lua_State *L, lua_State *from, int narg); IMPORT_SYMBOL(lua_status, int , lua_State *L); IMPORT_SYMBOL(lua_gc, int , lua_State *L, int what, int data); From 067271bc02d001e466f9fed4cfb9a56de93ec9a2 Mon Sep 17 00:00:00 2001 From: vqn <85911372+vqns@users.noreply.github.com> Date: Thu, 9 Feb 2023 18:26:32 +0100 Subject: [PATCH 036/148] fix incorrect x_offset if opened docs have different tab sizes (#1383) --- data/core/docview.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data/core/docview.lua b/data/core/docview.lua index 1c3ff6de..cdfb0298 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -168,10 +168,13 @@ end function DocView:get_col_x_offset(line, col) local default_font = self:get_font() + local _, indent_size = self.doc:get_indent_info() + default_font:set_tab_size(indent_size) local column = 1 local xoffset = 0 for _, type, text in self.doc.highlighter:each_token(line) do local font = style.syntax_fonts[type] or default_font + if font ~= default_font then font:set_tab_size(indent_size) end for char in common.utf8_chars(text) do if column == col then return xoffset @@ -190,8 +193,11 @@ function DocView:get_x_offset_col(line, x) local xoffset, last_i, i = 0, 1, 1 local default_font = self:get_font() + local _, indent_size = self.doc:get_indent_info() + default_font:set_tab_size(indent_size) for _, type, text in self.doc.highlighter:each_token(line) do local font = style.syntax_fonts[type] or default_font + if font ~= default_font then font:set_tab_size(indent_size) end for char in common.utf8_chars(text) do local w = font:get_width(char) if xoffset >= x then From 95611366bb81223354d8431b0dd1f732443a67b2 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 3 Mar 2023 11:42:31 +0100 Subject: [PATCH 037/148] Use correct view for scrolling to `find-replace:repeat-find` results (#1400) --- data/core/commands/findreplace.lua | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/data/core/commands/findreplace.lua b/data/core/commands/findreplace.lua index 4a456aae..312e55b2 100644 --- a/data/core/commands/findreplace.lua +++ b/data/core/commands/findreplace.lua @@ -240,34 +240,38 @@ command.add("core.docview!", { }) local function valid_for_finding() - return core.active_view:is(DocView) or core.active_view:is(CommandView) + -- Allow using this while in the CommandView + if core.active_view:is(CommandView) and last_view then + return true, last_view + end + return core.active_view:is(DocView), core.active_view end command.add(valid_for_finding, { - ["find-replace:repeat-find"] = function() + ["find-replace:repeat-find"] = function(dv) if not last_fn then core.error("No find to continue from") else - local sl1, sc1, sl2, sc2 = doc():get_selection(true) - local line1, col1, line2, col2 = last_fn(doc(), sl1, sc2, last_text, case_sensitive, find_regex, false) + local sl1, sc1, sl2, sc2 = dv.doc:get_selection(true) + local line1, col1, line2, col2 = last_fn(dv.doc, sl1, sc2, last_text, case_sensitive, find_regex, false) if line1 then - doc():set_selection(line2, col2, line1, col1) - last_view:scroll_to_line(line2, true) + dv.doc:set_selection(line2, col2, line1, col1) + dv:scroll_to_line(line2, true) else core.error("Couldn't find %q", last_text) end end end, - ["find-replace:previous-find"] = function() + ["find-replace:previous-find"] = function(dv) if not last_fn then core.error("No find to continue from") else - local sl1, sc1, sl2, sc2 = doc():get_selection(true) - local line1, col1, line2, col2 = last_fn(doc(), sl1, sc1, last_text, case_sensitive, find_regex, true) + local sl1, sc1, sl2, sc2 = dv.doc:get_selection(true) + local line1, col1, line2, col2 = last_fn(dv.doc, sl1, sc1, last_text, case_sensitive, find_regex, true) if line1 then - doc():set_selection(line2, col2, line1, col1) - last_view:scroll_to_line(line2, true) + dv.doc:set_selection(line2, col2, line1, col1) + dv:scroll_to_line(line2, true) else core.error("Couldn't find %q", last_text) end From f685293417a168234fd5f78e93793a3def8bb8cc Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Fri, 3 Mar 2023 22:07:45 +0800 Subject: [PATCH 038/148] Add manifest on Windows (#1405) * fix(gitignore): add exclusion for manifest files * feat(windows): add application manifest * feat(build): use application manifest on windows * refactor(build): use genrate_file to generate the manifest * style(manifest): remove trailing whitespace --- .gitignore | 1 + meson.build | 6 ++++ resources/windows/lite-xl.exe.manifest.in | 41 +++++++++++++++++++++++ resources/windows/manifest.rc | 4 +++ src/meson.build | 1 + 5 files changed, 53 insertions(+) create mode 100644 resources/windows/lite-xl.exe.manifest.in create mode 100644 resources/windows/manifest.rc diff --git a/.gitignore b/.gitignore index b1d18a64..9b248455 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ lite-xl* LiteXL* !resources/windows/*.diff +!resources/windows/*.exe.manifest.in diff --git a/meson.build b/meson.build index 7bbecc68..cfef8ec8 100644 --- a/meson.build +++ b/meson.build @@ -36,6 +36,7 @@ conf_data = configuration_data() conf_data.set('PROJECT_BUILD_DIR', meson.current_build_dir()) conf_data.set('PROJECT_SOURCE_DIR', meson.current_source_dir()) conf_data.set('PROJECT_VERSION', version) +conf_data.set('PROJECT_ASSEMBLY_VERSION', meson.project_version() + '.0') #=============================================================================== # Compiler Settings @@ -165,6 +166,11 @@ if get_option('portable') or host_machine.system() == 'windows' lite_bindir = '/' lite_docdir = '/doc' lite_datadir = '/data' + configure_file( + input: 'resources/windows/lite-xl.exe.manifest.in', + output: 'lite-xl.exe.manifest', + configuration: conf_data + ) elif get_option('bundle') and host_machine.system() == 'darwin' lite_cargs += '-DMACOS_USE_BUNDLE' lite_bindir = 'Contents/MacOS' diff --git a/resources/windows/lite-xl.exe.manifest.in b/resources/windows/lite-xl.exe.manifest.in new file mode 100644 index 00000000..9e787587 --- /dev/null +++ b/resources/windows/lite-xl.exe.manifest.in @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/windows/manifest.rc b/resources/windows/manifest.rc new file mode 100644 index 00000000..95b17e2d --- /dev/null +++ b/resources/windows/manifest.rc @@ -0,0 +1,4 @@ +#define IDR_RT_MANIFEST1 1 +#define RT_MANIFEST 24 + +IDR_RT_MANIFEST1 RT_MANIFEST "lite-xl.exe.manifest" diff --git a/src/meson.build b/src/meson.build index fee36d1d..a156ae3f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -50,6 +50,7 @@ lite_rc = [] if host_machine.system() == 'windows' windows = import('windows') lite_rc += windows.compile_resources('../resources/icons/icon.rc') + lite_rc += windows.compile_resources('../resources/windows/manifest.rc') elif host_machine.system() == 'darwin' lite_sources += 'bundle_open.m' endif From 8c47fad637d060b80e488b2dbcc065e20d9881d0 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Sat, 4 Mar 2023 21:23:09 +0100 Subject: [PATCH 039/148] Split `Command` struct into different structs for each command type (#1407) This reduces the space needed for each command. --- src/rencache.c | 54 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/rencache.c b/src/rencache.c index 5b930482..fda33e31 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -28,21 +28,36 @@ #define CELL_SIZE 96 #define CMD_BUF_RESIZE_RATE 1.2 #define CMD_BUF_INIT_SIZE (1024 * 512) -#define COMMAND_BARE_SIZE offsetof(Command, text) +#define COMMAND_BARE_SIZE offsetof(Command, command) -enum { SET_CLIP, DRAW_TEXT, DRAW_RECT }; +enum CommandType { SET_CLIP, DRAW_TEXT, DRAW_RECT }; + +typedef struct { + enum CommandType type; + uint32_t size; + /* Commands *must* always begin with a RenRect + ** This is done to ensure alignment */ + RenRect command[]; +} Command; + +typedef struct { + RenRect rect; +} SetClipCommand; typedef struct { - int8_t type; - int8_t tab_size; - int32_t size; RenRect rect; RenColor color; RenFont *fonts[FONT_FALLBACK_MAX]; float text_x; size_t len; + int8_t tab_size; char text[]; -} Command; +} DrawTextCommand; + +typedef struct { + RenRect rect; + RenColor color; +} DrawRectCommand; static unsigned cells_buf1[CELLS_X * CELLS_Y]; static unsigned cells_buf2[CELLS_X * CELLS_Y]; @@ -114,13 +129,14 @@ static bool expand_command_buffer() { return true; } -static Command* push_command(int type, int size) { +static void* push_command(enum CommandType type, int size) { if (resize_issue) { // Don't push new commands as we had problems resizing the command buffer. // Let's wait for the next frame. return NULL; } size_t alignment = alignof(max_align_t) - 1; + size += COMMAND_BARE_SIZE; size = (size + alignment) & ~alignment; int n = command_buf_idx + size; while (n > command_buf_size) { @@ -136,7 +152,7 @@ static Command* push_command(int type, int size) { memset(cmd, 0, size); cmd->type = type; cmd->size = size; - return cmd; + return cmd->command; } @@ -156,7 +172,7 @@ void rencache_show_debug(bool enable) { void rencache_set_clip_rect(RenRect rect) { - Command *cmd = push_command(SET_CLIP, COMMAND_BARE_SIZE); + SetClipCommand *cmd = push_command(SET_CLIP, sizeof(SetClipCommand)); if (cmd) { cmd->rect = intersect_rects(rect, screen_rect); last_clip_rect = cmd->rect; @@ -168,7 +184,7 @@ void rencache_draw_rect(RenRect rect, RenColor color) { if (rect.width == 0 || rect.height == 0 || !rects_overlap(last_clip_rect, rect)) { return; } - Command *cmd = push_command(DRAW_RECT, COMMAND_BARE_SIZE); + DrawRectCommand *cmd = push_command(DRAW_RECT, sizeof(DrawRectCommand)); if (cmd) { cmd->rect = rect; cmd->color = color; @@ -181,7 +197,7 @@ float rencache_draw_text(RenWindow *window_renderer, RenFont **fonts, const char RenRect rect = { x, y, (int)width, ren_font_group_get_height(fonts) }; if (rects_overlap(last_clip_rect, rect)) { int sz = len + 1; - Command *cmd = push_command(DRAW_TEXT, COMMAND_BARE_SIZE + sz); + DrawTextCommand *cmd = push_command(DRAW_TEXT, sizeof(DrawTextCommand) + sz); if (cmd) { memcpy(cmd->text, text, sz); cmd->color = color; @@ -249,8 +265,9 @@ void rencache_end_frame(RenWindow *window_renderer) { Command *cmd = NULL; RenRect cr = screen_rect; while (next_command(&cmd)) { - if (cmd->type == SET_CLIP) { cr = cmd->rect; } - RenRect r = intersect_rects(cmd->rect, cr); + /* cmd->command[0] should always be the Command rect */ + if (cmd->type == SET_CLIP) { cr = cmd->command[0]; } + RenRect r = intersect_rects(cmd->command[0], cr); if (r.width == 0 || r.height == 0) { continue; } unsigned h = HASH_INITIAL; hash(&h, cmd, cmd->size); @@ -290,16 +307,19 @@ void rencache_end_frame(RenWindow *window_renderer) { cmd = NULL; while (next_command(&cmd)) { + SetClipCommand *ccmd = (SetClipCommand*)&cmd->command; + DrawRectCommand *rcmd = (DrawRectCommand*)&cmd->command; + DrawTextCommand *tcmd = (DrawTextCommand*)&cmd->command; switch (cmd->type) { case SET_CLIP: - ren_set_clip_rect(window_renderer, intersect_rects(cmd->rect, r)); + ren_set_clip_rect(window_renderer, intersect_rects(ccmd->rect, r)); break; case DRAW_RECT: - ren_draw_rect(window_renderer, cmd->rect, cmd->color); + ren_draw_rect(window_renderer, rcmd->rect, rcmd->color); break; case DRAW_TEXT: - ren_font_group_set_tab_size(cmd->fonts, cmd->tab_size); - ren_draw_text(window_renderer, cmd->fonts, cmd->text, cmd->len, cmd->text_x, cmd->rect.y, cmd->color); + ren_font_group_set_tab_size(tcmd->fonts, tcmd->tab_size); + ren_draw_text(window_renderer, tcmd->fonts, tcmd->text, tcmd->len, tcmd->text_x, tcmd->rect.y, tcmd->color); break; } } From 32860c111e4506e7c6b190163037e7b9df7da5e3 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Thu, 9 Mar 2023 21:58:32 +0800 Subject: [PATCH 040/148] refactor(main): move SetProcessDPIAware to manifests (#1413) --- resources/windows/lite-xl.exe.manifest.in | 7 +++++++ src/main.c | 6 +----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/resources/windows/lite-xl.exe.manifest.in b/resources/windows/lite-xl.exe.manifest.in index 9e787587..a01ac8d2 100644 --- a/resources/windows/lite-xl.exe.manifest.in +++ b/resources/windows/lite-xl.exe.manifest.in @@ -24,6 +24,13 @@ /> + + + + true + + + diff --git a/src/main.c b/src/main.c index 32212df8..174e4372 100644 --- a/src/main.c +++ b/src/main.c @@ -120,11 +120,7 @@ void set_macos_bundle_resources(lua_State *L); #endif int main(int argc, char **argv) { -#ifdef _WIN32 - HINSTANCE lib = LoadLibrary("user32.dll"); - int (*SetProcessDPIAware)() = (void*) GetProcAddress(lib, "SetProcessDPIAware"); - SetProcessDPIAware(); -#else +#ifndef _WIN32 signal(SIGPIPE, SIG_IGN); #endif From 1d0725f9044eb556170ca2d14ca2f14d88fa4efb Mon Sep 17 00:00:00 2001 From: Guldoman Date: Thu, 9 Mar 2023 16:48:46 +0100 Subject: [PATCH 041/148] Improve text width calculation precision (#1408) In some extreme cases (~30000 chars) text width precision takes a hit. Using double instead of float fixes that. --- src/api/renderer.c | 2 +- src/rencache.c | 4 ++-- src/rencache.h | 2 +- src/renderer.c | 12 ++++++------ src/renderer.h | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/api/renderer.c b/src/api/renderer.c index d96fbe0a..b619b586 100644 --- a/src/api/renderer.c +++ b/src/api/renderer.c @@ -345,7 +345,7 @@ static int f_draw_text(lua_State *L) { size_t len; const char *text = luaL_checklstring(L, 2, &len); - float x = luaL_checknumber(L, 3); + double x = luaL_checknumber(L, 3); int y = luaL_checknumber(L, 4); RenColor color = checkcolor(L, 5, 255); x = rencache_draw_text(&window_renderer, fonts, text, len, x, y, color); diff --git a/src/rencache.c b/src/rencache.c index fda33e31..946aa3fb 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -191,9 +191,9 @@ void rencache_draw_rect(RenRect rect, RenColor color) { } } -float rencache_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) +double rencache_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, double x, int y, RenColor color) { - float width = ren_font_group_get_width(window_renderer, fonts, text, len); + double width = ren_font_group_get_width(window_renderer, fonts, text, len); RenRect rect = { x, y, (int)width, ren_font_group_get_height(fonts) }; if (rects_overlap(last_clip_rect, rect)) { int sz = len + 1; diff --git a/src/rencache.h b/src/rencache.h index 925b50f0..2453d808 100644 --- a/src/rencache.h +++ b/src/rencache.h @@ -8,7 +8,7 @@ void rencache_show_debug(bool enable); void rencache_set_clip_rect(RenRect rect); void rencache_draw_rect(RenRect rect, RenColor color); -float rencache_draw_text(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, float x, int y, RenColor color); +double rencache_draw_text(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, double x, int y, RenColor color); void rencache_invalidate(void); void rencache_begin_frame(RenWindow *window_renderer); void rencache_end_frame(RenWindow *window_renderer); diff --git a/src/renderer.c b/src/renderer.c index 53be1046..59004bc0 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -360,8 +360,8 @@ int ren_font_group_get_height(RenFont **fonts) { return fonts[0]->height; } -float ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len) { - float width = 0; +double ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len) { + double width = 0; const char* end = text + len; GlyphMetric* metric = NULL; GlyphSet* set = NULL; while (text < end) { @@ -376,12 +376,12 @@ float ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, cons return width / surface_scale; } -float ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { +double ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { SDL_Surface *surface = renwin_get_surface(window_renderer); const RenRect clip = window_renderer->clip; const int surface_scale = renwin_surface_scale(window_renderer); - float pen_x = x * surface_scale; + double pen_x = x * surface_scale; y *= surface_scale; int bytes_per_pixel = surface->format->BytesPerPixel; const char* end = text + len; @@ -389,7 +389,7 @@ float ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *tex int clip_end_x = clip.x + clip.width, clip_end_y = clip.y + clip.height; RenFont* last = NULL; - float last_pen_x = x; + double last_pen_x = x; bool underline = fonts[0]->style & FONT_STYLE_UNDERLINE; bool strikethrough = fonts[0]->style & FONT_STYLE_STRIKETHROUGH; @@ -453,7 +453,7 @@ float ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *tex if(!last) last = font; else if(font != last || text == end) { - float local_pen_x = text == end ? pen_x + adv : pen_x; + double local_pen_x = text == end ? pen_x + adv : pen_x; if (underline) ren_draw_rect(window_renderer, (RenRect){last_pen_x, y / surface_scale + last->height - 1, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color); if (strikethrough) diff --git a/src/renderer.h b/src/renderer.h index 46e04341..3897421e 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -33,8 +33,8 @@ int ren_font_group_get_height(RenFont **font); float ren_font_group_get_size(RenFont **font); void ren_font_group_set_size(RenWindow *window_renderer, RenFont **font, float size); void ren_font_group_set_tab_size(RenFont **font, int n); -float ren_font_group_get_width(RenWindow *window_renderer, RenFont **font, const char *text, size_t len); -float ren_draw_text(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, float x, int y, RenColor color); +double ren_font_group_get_width(RenWindow *window_renderer, RenFont **font, const char *text, size_t len); +double ren_draw_text(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, float x, int y, RenColor color); void ren_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color); From a61531dbf02cfb72292ce71d802210b34859599c Mon Sep 17 00:00:00 2001 From: Guldoman Date: Tue, 14 Mar 2023 16:39:00 +0100 Subject: [PATCH 042/148] Use clipping functions provided by SDL (#1426) --- src/renderer.c | 31 ++++++++++++++----------------- src/renwindow.c | 6 ++++-- src/renwindow.h | 1 - 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/renderer.c b/src/renderer.c index 59004bc0..226dbe71 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -378,7 +378,8 @@ double ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, con double ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { SDL_Surface *surface = renwin_get_surface(window_renderer); - const RenRect clip = window_renderer->clip; + SDL_Rect clip; + SDL_GetClipRect(surface, &clip); const int surface_scale = renwin_surface_scale(window_renderer); double pen_x = x * surface_scale; @@ -386,7 +387,7 @@ double ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *te int bytes_per_pixel = surface->format->BytesPerPixel; const char* end = text + len; uint8_t* destination_pixels = surface->pixels; - int clip_end_x = clip.x + clip.width, clip_end_y = clip.y + clip.height; + int clip_end_x = clip.x + clip.w, clip_end_y = clip.y + clip.h; RenFont* last = NULL; double last_pen_x = x; @@ -479,28 +480,24 @@ static inline RenColor blend_pixel(RenColor dst, RenColor src) { void ren_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color) { if (color.a == 0) { return; } + SDL_Surface *surface = renwin_get_surface(window_renderer); const int surface_scale = renwin_surface_scale(window_renderer); - /* transforms coordinates in pixels. */ - rect.x *= surface_scale; - rect.y *= surface_scale; - rect.width *= surface_scale; - rect.height *= surface_scale; + SDL_Rect dest_rect = { rect.x * surface_scale, + rect.y * surface_scale, + rect.width * surface_scale, + rect.height * surface_scale }; - const RenRect clip = window_renderer->clip; - int x1 = rect.x < clip.x ? clip.x : rect.x; - int y1 = rect.y < clip.y ? clip.y : rect.y; - int x2 = rect.x + rect.width; - int y2 = rect.y + rect.height; - x2 = x2 > clip.x + clip.width ? clip.x + clip.width : x2; - y2 = y2 > clip.y + clip.height ? clip.y + clip.height : y2; - - SDL_Surface *surface = renwin_get_surface(window_renderer); - SDL_Rect dest_rect = { x1, y1, x2 - x1, y2 - y1 }; if (color.a == 0xff) { uint32_t translated = SDL_MapRGB(surface->format, color.r, color.g, color.b); SDL_FillRect(surface, &dest_rect, translated); } else { + // Seems like SDL doesn't handle clipping as we expect when using + // scaled blitting, so we "clip" manually. + SDL_Rect clip; + SDL_GetClipRect(surface, &clip); + if (!SDL_IntersectRect(&clip, &dest_rect, &dest_rect)) return; + uint32_t *pixel = (uint32_t *)draw_rect_surface->pixels; *pixel = SDL_MapRGBA(draw_rect_surface->format, color.r, color.g, color.b, color.a); SDL_BlitScaled(draw_rect_surface, NULL, surface, &dest_rect); diff --git a/src/renwindow.c b/src/renwindow.c index 85fd7a07..c700cedf 100644 --- a/src/renwindow.c +++ b/src/renwindow.c @@ -61,12 +61,14 @@ static RenRect scaled_rect(const RenRect rect, const int scale) { void renwin_clip_to_surface(RenWindow *ren) { SDL_Surface *surface = renwin_get_surface(ren); - ren->clip = (RenRect) {0, 0, surface->w, surface->h}; + SDL_SetClipRect(surface, NULL); } void renwin_set_clip_rect(RenWindow *ren, RenRect rect) { - ren->clip = scaled_rect(rect, renwin_surface_scale(ren)); + SDL_Surface *surface = renwin_get_surface(ren); + RenRect sr = scaled_rect(rect, renwin_surface_scale(ren)); + SDL_SetClipRect(surface, &(SDL_Rect){.x = sr.x, .y = sr.y, .w = sr.width, .h = sr.height}); } diff --git a/src/renwindow.h b/src/renwindow.h index 8edc03d8..7f08aa2f 100644 --- a/src/renwindow.h +++ b/src/renwindow.h @@ -3,7 +3,6 @@ struct RenWindow { SDL_Window *window; - RenRect clip; /* Clipping rect in pixel coordinates. */ #ifdef LITE_USE_SDL_RENDERER SDL_Renderer *renderer; SDL_Texture *texture; From 89864ee88c9c9da08b6237990e9c2f7e3f79ae03 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Sun, 19 Mar 2023 20:39:52 +0100 Subject: [PATCH 043/148] Aggregate `SDL_Surface`s and their scale in `RenSurface` (#1429) --- src/rencache.c | 8 +++++--- src/renderer.c | 31 +++++++++++++++---------------- src/renderer.h | 5 +++-- src/renwindow.c | 43 +++++++++++++++++-------------------------- src/renwindow.h | 6 ++---- 5 files changed, 42 insertions(+), 51 deletions(-) diff --git a/src/rencache.c b/src/rencache.c index 946aa3fb..928d0b0d 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -17,6 +17,7 @@ #include #include "rencache.h" +#include "renwindow.h" /* a cache over the software renderer -- all drawing operations are stored as ** commands when issued. At the end of the frame we write the commands to a grid @@ -299,6 +300,7 @@ void rencache_end_frame(RenWindow *window_renderer) { *r = intersect_rects(*r, screen_rect); } + RenSurface rs = renwin_get_surface(window_renderer); /* redraw updated regions */ for (int i = 0; i < rect_count; i++) { /* draw */ @@ -315,18 +317,18 @@ void rencache_end_frame(RenWindow *window_renderer) { ren_set_clip_rect(window_renderer, intersect_rects(ccmd->rect, r)); break; case DRAW_RECT: - ren_draw_rect(window_renderer, rcmd->rect, rcmd->color); + ren_draw_rect(&rs, rcmd->rect, rcmd->color); break; case DRAW_TEXT: ren_font_group_set_tab_size(tcmd->fonts, tcmd->tab_size); - ren_draw_text(window_renderer, tcmd->fonts, tcmd->text, tcmd->len, tcmd->text_x, tcmd->rect.y, tcmd->color); + ren_draw_text(&rs, tcmd->fonts, tcmd->text, tcmd->len, tcmd->text_x, tcmd->rect.y, tcmd->color); break; } } if (show_debug) { RenColor color = { rand(), rand(), rand(), 50 }; - ren_draw_rect(window_renderer, r, color); + ren_draw_rect(&rs, r, color); } } diff --git a/src/renderer.c b/src/renderer.c index 226dbe71..e9e715ef 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -257,7 +257,7 @@ RenFont* ren_font_load(RenWindow *window_renderer, const char* path, float size, #endif - const int surface_scale = renwin_surface_scale(window_renderer); + const int surface_scale = renwin_get_surface(window_renderer).scale; if (FT_Set_Pixel_Sizes(face, 0, (int)(size*surface_scale))) goto failure; int len = strlen(path); @@ -342,7 +342,7 @@ float ren_font_group_get_size(RenFont **fonts) { } void ren_font_group_set_size(RenWindow *window_renderer, RenFont **fonts, float size) { - const int surface_scale = renwin_surface_scale(window_renderer); + const int surface_scale = renwin_get_surface(window_renderer).scale; for (int i = 0; i < FONT_FALLBACK_MAX && fonts[i]; ++i) { font_clear_glyph_cache(fonts[i]); FT_Face face = fonts[i]->face; @@ -372,16 +372,16 @@ double ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, con break; width += (!font || metric->xadvance) ? metric->xadvance : fonts[0]->space_advance; } - const int surface_scale = renwin_surface_scale(window_renderer); + const int surface_scale = renwin_get_surface(window_renderer).scale; return width / surface_scale; } -double ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { - SDL_Surface *surface = renwin_get_surface(window_renderer); +double ren_draw_text(RenSurface *rs, RenFont **fonts, const char *text, size_t len, float x, int y, RenColor color) { + SDL_Surface *surface = rs->surface; SDL_Rect clip; SDL_GetClipRect(surface, &clip); - const int surface_scale = renwin_surface_scale(window_renderer); + const int surface_scale = rs->scale; double pen_x = x * surface_scale; y *= surface_scale; int bytes_per_pixel = surface->format->BytesPerPixel; @@ -405,7 +405,7 @@ double ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *te int end_x = (metric->x1 - metric->x0) + start_x; int glyph_end = metric->x1, glyph_start = metric->x0; if (!metric->loaded && codepoint > 0xFF) - ren_draw_rect(window_renderer, (RenRect){ start_x + 1, y, font->space_advance - 1, ren_font_group_get_height(fonts) }, color); + ren_draw_rect(rs, (RenRect){ start_x + 1, y, font->space_advance - 1, ren_font_group_get_height(fonts) }, color); if (set->surface && color.a > 0 && end_x >= clip.x && start_x < clip_end_x) { uint8_t* source_pixels = set->surface->pixels; for (int line = metric->y0; line < metric->y1; ++line) { @@ -456,9 +456,9 @@ double ren_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *te else if(font != last || text == end) { double local_pen_x = text == end ? pen_x + adv : pen_x; if (underline) - ren_draw_rect(window_renderer, (RenRect){last_pen_x, y / surface_scale + last->height - 1, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color); + ren_draw_rect(rs, (RenRect){last_pen_x, y / surface_scale + last->height - 1, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color); if (strikethrough) - ren_draw_rect(window_renderer, (RenRect){last_pen_x, y / surface_scale + last->height / 2, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color); + ren_draw_rect(rs, (RenRect){last_pen_x, y / surface_scale + last->height / 2, (local_pen_x - last_pen_x) / surface_scale, last->underline_thickness * surface_scale}, color); last = font; last_pen_x = pen_x; } @@ -477,11 +477,11 @@ static inline RenColor blend_pixel(RenColor dst, RenColor src) { return dst; } -void ren_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color) { +void ren_draw_rect(RenSurface *rs, RenRect rect, RenColor color) { if (color.a == 0) { return; } - SDL_Surface *surface = renwin_get_surface(window_renderer); - const int surface_scale = renwin_surface_scale(window_renderer); + SDL_Surface *surface = rs->surface; + const int surface_scale = rs->scale; SDL_Rect dest_rect = { rect.x * surface_scale, rect.y * surface_scale, @@ -552,8 +552,7 @@ void ren_set_clip_rect(RenWindow *window_renderer, RenRect rect) { void ren_get_size(RenWindow *window_renderer, int *x, int *y) { - const int scale = renwin_surface_scale(window_renderer); - SDL_Surface *surface = renwin_get_surface(window_renderer); - *x = surface->w / scale; - *y = surface->h / scale; + RenSurface rs = renwin_get_surface(window_renderer); + *x = rs.surface->w / rs.scale; + *y = rs.surface->h / rs.scale; } diff --git a/src/renderer.h b/src/renderer.h index 3897421e..0e96d9a9 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -19,6 +19,7 @@ typedef enum { FONT_ANTIALIASING_NONE, FONT_ANTIALIASING_GRAYSCALE, FONT_ANTIALI typedef enum { FONT_STYLE_BOLD = 1, FONT_STYLE_ITALIC = 2, FONT_STYLE_UNDERLINE = 4, FONT_STYLE_SMOOTH = 8, FONT_STYLE_STRIKETHROUGH = 16 } ERenFontStyle; typedef struct { uint8_t b, g, r, a; } RenColor; typedef struct { int x, y, width, height; } RenRect; +typedef struct { SDL_Surface *surface; int scale; } RenSurface; struct RenWindow; typedef struct RenWindow RenWindow; @@ -34,9 +35,9 @@ float ren_font_group_get_size(RenFont **font); void ren_font_group_set_size(RenWindow *window_renderer, RenFont **font, float size); void ren_font_group_set_tab_size(RenFont **font, int n); double ren_font_group_get_width(RenWindow *window_renderer, RenFont **font, const char *text, size_t len); -double ren_draw_text(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, float x, int y, RenColor color); +double ren_draw_text(RenSurface *rs, RenFont **font, const char *text, size_t len, float x, int y, RenColor color); -void ren_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color); +void ren_draw_rect(RenSurface *rs, RenRect rect, RenColor color); void ren_init(SDL_Window *win); void ren_resize_window(RenWindow *window_renderer); diff --git a/src/renwindow.c b/src/renwindow.c index c700cedf..ba671404 100644 --- a/src/renwindow.c +++ b/src/renwindow.c @@ -24,20 +24,20 @@ static void setup_renderer(RenWindow *ren, int w, int h) { SDL_DestroyTexture(ren->texture); } ren->texture = SDL_CreateTexture(ren->renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STREAMING, w, h); - ren->surface_scale = query_surface_scale(ren); + ren->rensurface.scale = query_surface_scale(ren); } #endif void renwin_init_surface(UNUSED RenWindow *ren) { #ifdef LITE_USE_SDL_RENDERER - if (ren->surface) { - SDL_FreeSurface(ren->surface); + if (ren->rensurface.surface) { + SDL_FreeSurface(ren->rensurface.surface); } int w, h; SDL_GL_GetDrawableSize(ren->window, &w, &h); - ren->surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_BGRA32); - if (!ren->surface) { + ren->rensurface.surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_BGRA32); + if (!ren->rensurface.surface) { fprintf(stderr, "Error creating surface: %s", SDL_GetError()); exit(1); } @@ -45,14 +45,6 @@ void renwin_init_surface(UNUSED RenWindow *ren) { #endif } -int renwin_surface_scale(UNUSED RenWindow *ren) { -#ifdef LITE_USE_SDL_RENDERER - return ren->surface_scale; -#else - return 1; -#endif -} - static RenRect scaled_rect(const RenRect rect, const int scale) { return (RenRect) {rect.x * scale, rect.y * scale, rect.width * scale, rect.height * scale}; @@ -60,28 +52,27 @@ static RenRect scaled_rect(const RenRect rect, const int scale) { void renwin_clip_to_surface(RenWindow *ren) { - SDL_Surface *surface = renwin_get_surface(ren); - SDL_SetClipRect(surface, NULL); + SDL_SetClipRect(renwin_get_surface(ren).surface, NULL); } void renwin_set_clip_rect(RenWindow *ren, RenRect rect) { - SDL_Surface *surface = renwin_get_surface(ren); - RenRect sr = scaled_rect(rect, renwin_surface_scale(ren)); - SDL_SetClipRect(surface, &(SDL_Rect){.x = sr.x, .y = sr.y, .w = sr.width, .h = sr.height}); + RenSurface rs = renwin_get_surface(ren); + RenRect sr = scaled_rect(rect, rs.scale); + SDL_SetClipRect(rs.surface, &(SDL_Rect){.x = sr.x, .y = sr.y, .w = sr.width, .h = sr.height}); } -SDL_Surface *renwin_get_surface(RenWindow *ren) { +RenSurface renwin_get_surface(RenWindow *ren) { #ifdef LITE_USE_SDL_RENDERER - return ren->surface; + return ren->rensurface; #else SDL_Surface *surface = SDL_GetWindowSurface(ren->window); if (!surface) { fprintf(stderr, "Error getting window surface: %s", SDL_GetError()); exit(1); } - return surface; + return (RenSurface){.surface = surface, .scale = 1}; #endif } @@ -90,7 +81,7 @@ void renwin_resize_surface(UNUSED RenWindow *ren) { int new_w, new_h; SDL_GL_GetDrawableSize(ren->window, &new_w, &new_h); /* Note that (w, h) may differ from (new_w, new_h) on retina displays. */ - if (new_w != ren->surface->w || new_h != ren->surface->h) { + if (new_w != ren->rensurface.surface->w || new_h != ren->rensurface.surface->h) { renwin_init_surface(ren); renwin_clip_to_surface(ren); setup_renderer(ren, new_w, new_h); @@ -104,14 +95,14 @@ void renwin_show_window(RenWindow *ren) { void renwin_update_rects(RenWindow *ren, RenRect *rects, int count) { #ifdef LITE_USE_SDL_RENDERER - const int scale = ren->surface_scale; + const int scale = ren->rensurface.scale; for (int i = 0; i < count; i++) { const RenRect *r = &rects[i]; const int x = scale * r->x, y = scale * r->y; const int w = scale * r->width, h = scale * r->height; const SDL_Rect sr = {.x = x, .y = y, .w = w, .h = h}; - int32_t *pixels = ((int32_t *) ren->surface->pixels) + x + ren->surface->w * y; - SDL_UpdateTexture(ren->texture, &sr, pixels, ren->surface->w * 4); + int32_t *pixels = ((int32_t *) ren->rensurface.surface->pixels) + x + ren->rensurface.surface->w * y; + SDL_UpdateTexture(ren->texture, &sr, pixels, ren->rensurface.surface->w * 4); } SDL_RenderCopy(ren->renderer, ren->texture, NULL, NULL); SDL_RenderPresent(ren->renderer); @@ -126,6 +117,6 @@ void renwin_free(RenWindow *ren) { #ifdef LITE_USE_SDL_RENDERER SDL_DestroyTexture(ren->texture); SDL_DestroyRenderer(ren->renderer); - SDL_FreeSurface(ren->surface); + SDL_FreeSurface(ren->rensurface.surface); #endif } diff --git a/src/renwindow.h b/src/renwindow.h index 7f08aa2f..6b0b9eaa 100644 --- a/src/renwindow.h +++ b/src/renwindow.h @@ -6,19 +6,17 @@ struct RenWindow { #ifdef LITE_USE_SDL_RENDERER SDL_Renderer *renderer; SDL_Texture *texture; - SDL_Surface *surface; - int surface_scale; + RenSurface rensurface; #endif }; typedef struct RenWindow RenWindow; void renwin_init_surface(RenWindow *ren); -int renwin_surface_scale(RenWindow *ren); void renwin_clip_to_surface(RenWindow *ren); void renwin_set_clip_rect(RenWindow *ren, RenRect rect); void renwin_resize_surface(RenWindow *ren); void renwin_show_window(RenWindow *ren); void renwin_update_rects(RenWindow *ren, RenRect *rects, int count); void renwin_free(RenWindow *ren); -SDL_Surface *renwin_get_surface(RenWindow *ren); +RenSurface renwin_get_surface(RenWindow *ren); From 84c7bb9de69a0c0911dfb1b109e7f8743354717a Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Wed, 22 Mar 2023 20:36:05 +0800 Subject: [PATCH 044/148] Asynchronous process reaping (#1412) * refactor(process): introduce process_stream_handle separate from process_handle * feat(process): introduce process_handle helper functions * feat(process): add asynchronous process reaping * feat(process): wait for shorter period if possible * style(process): remove unecessary brackets * style(process): fix parentheses * refactor(process): remove useless setvbuf call * style(process): remove unecessary value * refactor(process): add size field into kill_list * refactor(process): use SDL_Delay for sleeping * style(process): remove trailing whitespace * fix(main): destroy window before closing lua * fix(process): check for timeout correctly * refactor(process): remove unecessary if check * refactor(process): remove size from the list * fix(process): fix invalid delay calculation Co-authored-by: Guldoman --------- Co-authored-by: Guldoman --- src/api/process.c | 312 ++++++++++++++++++++++++++++++++++++++-------- src/main.c | 4 +- 2 files changed, 262 insertions(+), 54 deletions(-) diff --git a/src/api/process.c b/src/api/process.c index 081e6ab6..2b0a5008 100644 --- a/src/api/process.c +++ b/src/api/process.c @@ -5,12 +5,13 @@ #include #include #include +#include #include #if _WIN32 // https://stackoverflow.com/questions/60645/overlapped-i-o-on-anonymous-pipe // https://docs.microsoft.com/en-us/windows/win32/procthread/creating-a-child-process-with-redirected-input-and-output - #include + #include #else #include #include @@ -21,11 +22,15 @@ #endif #define READ_BUF_SIZE 2048 +#define PROCESS_TERM_TRIES 3 +#define PROCESS_TERM_DELAY 50 #if _WIN32 +typedef HANDLE process_stream_handle; typedef HANDLE process_handle; #else -typedef int process_handle; +typedef int process_stream_handle; +typedef pid_t process_handle; #endif typedef struct { @@ -38,9 +43,24 @@ typedef struct { bool reading[2]; char buffer[2][READ_BUF_SIZE]; #endif - process_handle child_pipes[3][2]; + process_stream_handle child_pipes[3][2]; } process_t; +typedef struct process_kill_s { + int tries; + uint32_t start_time; + process_handle handle; + struct process_kill_s *next; +} process_kill_t; + +typedef struct { + bool stop; + SDL_mutex *mutex; + SDL_cond *has_work, *work_done; + process_kill_t *head; + process_kill_t *tail; +} process_kill_list_t; + typedef enum { SIGNAL_KILL, SIGNAL_TERM, @@ -63,60 +83,201 @@ typedef enum { REDIRECT_PARENT = -3, } filed_e; +static process_kill_list_t kill_list = { 0 }; +static SDL_Thread *kill_list_thread = NULL; + #ifdef _WIN32 static volatile long PipeSerialNumber; static void close_fd(HANDLE* handle) { if (*handle) CloseHandle(*handle); *handle = INVALID_HANDLE_VALUE; } + #define PROCESS_GET_HANDLE(P) ((P)->process_information.hProcess) #else static void close_fd(int* fd) { if (*fd) close(*fd); *fd = 0; } + #define PROCESS_GET_HANDLE(P) ((P)->pid) #endif + +static void kill_list_free(process_kill_list_t *list) { + process_kill_t *node, *temp; + SDL_DestroyMutex(list->mutex); + SDL_DestroyCond(list->has_work); + SDL_DestroyCond(list->work_done); + node = list->head; + while (node) { + temp = node; + node = node->next; + free(temp); + } +} + + +static bool kill_list_init(process_kill_list_t *list) { + list->mutex = SDL_CreateMutex(); + list->has_work = SDL_CreateCond(); + list->work_done = SDL_CreateCond(); + list->head = list->tail = NULL; + list->stop = false; + if (!list->mutex || !list->has_work || !list->work_done) { + kill_list_free(list); + return false; + } + return true; +} + + +static void kill_list_push(process_kill_list_t *list, process_kill_t *task) { + if (!list) return; + task->next = NULL; + if (list->tail) { + list->tail->next = task; + list->tail = task; + } else { + list->head = list->tail = task; + } +} + + +static void kill_list_pop(process_kill_list_t *list) { + if (!list || !list->head) return; + process_kill_t *head = list->head; + list->head = list->head->next; + if (!list->head) list->tail = NULL; + head->next = NULL; +} + + +static void kill_list_wait_all(process_kill_list_t *list) { + SDL_LockMutex(list->mutex); + // wait until list is empty + while (list->head) + SDL_CondWait(list->work_done, list->mutex); + // tell the worker to stop + list->stop = true; + SDL_CondSignal(list->has_work); + SDL_UnlockMutex(list->mutex); +} + + +static void process_handle_close(process_handle *handle) { +#ifdef _WIN32 + if (*handle) { + CloseHandle(*handle); + *handle = NULL; + } +#endif + (void) 0; +} + + +static bool process_handle_is_running(process_handle handle, int *status) { +#ifdef _WIN32 + DWORD s; + if (GetExitCodeProcess(handle, &s) && s != STILL_ACTIVE) { + if (status != NULL) + *status = s; + return false; + } +#else + int s; + if (waitpid(handle, &s, WNOHANG) != 0) { + if (status != NULL) + *status = WEXITSTATUS(s); + return false; + } +#endif + return true; +} + + +static bool process_handle_signal(process_handle handle, signal_e sig) { +#if _WIN32 + switch(sig) { + case SIGNAL_TERM: return GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, GetProcessId(handle)); + case SIGNAL_KILL: return TerminateProcess(handle, -1); + case SIGNAL_INTERRUPT: return DebugBreakProcess(handle); + } +#else + switch (sig) { + case SIGNAL_TERM: return kill(-handle, SIGTERM) == 0; break; + case SIGNAL_KILL: return kill(-handle, SIGKILL) == 0; break; + case SIGNAL_INTERRUPT: return kill(-handle, SIGINT) == 0; break; + } +#endif + return false; +} + + +static int kill_list_worker(void *ud) { + process_kill_list_t *list = (process_kill_list_t *) ud; + process_kill_t *current_task; + uint32_t delay; + + while (true) { + SDL_LockMutex(list->mutex); + + // wait until we have work to do + while (!list->head && !list->stop) + SDL_CondWait(list->has_work, list->mutex); // LOCK MUTEX + + if (list->stop) break; + + while ((current_task = list->head)) { + if ((SDL_GetTicks() - current_task->start_time) < PROCESS_TERM_DELAY) + break; + kill_list_pop(list); + if (process_handle_is_running(current_task->handle, NULL)) { + if (current_task->tries < PROCESS_TERM_TRIES) + process_handle_signal(current_task->handle, SIGNAL_TERM); + else if (current_task->tries == PROCESS_TERM_TRIES) + process_handle_signal(current_task->handle, SIGNAL_KILL); + else + goto free_task; + + // add the task back into the queue + current_task->tries++; + current_task->start_time = SDL_GetTicks(); + kill_list_push(list, current_task); + } else { + free_task: + SDL_CondSignal(list->work_done); + process_handle_close(¤t_task->handle); + free(current_task); + } + } + delay = list->head ? (list->head->start_time + PROCESS_TERM_DELAY) - SDL_GetTicks() : 0; + SDL_UnlockMutex(list->mutex); + SDL_Delay(delay); + } + SDL_UnlockMutex(list->mutex); + return 0; +} + + static bool poll_process(process_t* proc, int timeout) { + uint32_t ticks; + if (!proc->running) return false; - uint32_t ticks = SDL_GetTicks(); + if (timeout == WAIT_DEADLINE) timeout = proc->deadline; + ticks = SDL_GetTicks(); do { - #ifdef _WIN32 - DWORD exit_code = -1; - if (!GetExitCodeProcess( proc->process_information.hProcess, &exit_code ) || exit_code != STILL_ACTIVE) { - proc->returncode = exit_code; - proc->running = false; - break; - } - #else - int status; - pid_t wait_response = waitpid(proc->pid, &status, WNOHANG); - if (wait_response != 0) { - proc->running = false; - proc->returncode = WEXITSTATUS(status); - break; - } - #endif + int status; + if (!process_handle_is_running(PROCESS_GET_HANDLE(proc), &status)) { + proc->running = false; + proc->returncode = status; + break; + } if (timeout) - SDL_Delay(5); + SDL_Delay(timeout >= 5 ? 5 : 0); } while (timeout == WAIT_INFINITE || (int)SDL_GetTicks() - ticks < timeout); return proc->running; } static bool signal_process(process_t* proc, signal_e sig) { - bool terminate = false; - #if _WIN32 - switch(sig) { - case SIGNAL_TERM: terminate = GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, GetProcessId(proc->process_information.hProcess)); break; - case SIGNAL_KILL: terminate = TerminateProcess(proc->process_information.hProcess, -1); break; - case SIGNAL_INTERRUPT: DebugBreakProcess(proc->process_information.hProcess); break; - } - #else - switch (sig) { - case SIGNAL_TERM: terminate = kill(-proc->pid, SIGTERM) == 1; break; - case SIGNAL_KILL: terminate = kill(-proc->pid, SIGKILL) == 1; break; - case SIGNAL_INTERRUPT: kill(-proc->pid, SIGINT); break; - } - #endif - if (terminate) + if (process_handle_signal(PROCESS_GET_HANDLE(proc), sig)) poll_process(proc, WAIT_NONE); return true; } @@ -152,7 +313,7 @@ static int process_start(lua_State* L) { if (arg_len > 1) { lua_getfield(L, 2, "env"); if (!lua_isnil(L, -1)) { - lua_pushnil(L); + lua_pushnil(L); while (lua_next(L, -2) != 0) { const char* key = luaL_checklstring(L, -2, &key_len); const char* val = luaL_checklstring(L, -1, &val_len); @@ -179,7 +340,7 @@ static int process_start(lua_State* L) { } } } - + process_t* self = lua_newuserdata(L, sizeof(process_t)); memset(self, 0, sizeof(process_t)); luaL_setmetatable(L, API_TYPE_PROCESS); @@ -196,9 +357,9 @@ static int process_start(lua_State* L) { } self->child_pipes[i][i == STDIN_FD ? 1 : 0] = INVALID_HANDLE_VALUE; break; - case REDIRECT_DISCARD: - self->child_pipes[i][0] = INVALID_HANDLE_VALUE; - self->child_pipes[i][1] = INVALID_HANDLE_VALUE; + case REDIRECT_DISCARD: + self->child_pipes[i][0] = INVALID_HANDLE_VALUE; + self->child_pipes[i][1] = INVALID_HANDLE_VALUE; break; default: { if (new_fds[i] == i) { @@ -289,7 +450,7 @@ static int process_start(lua_State* L) { goto cleanup; } self->pid = (long)self->process_information.dwProcessId; - if (detach) + if (detach) CloseHandle(self->process_information.hProcess); CloseHandle(self->process_information.hThread); #else @@ -372,7 +533,7 @@ static int process_start(lua_State* L) { free((char*)env_values[i]); } for (int stream = 0; stream < 3; ++stream) { - process_handle* pipe = &self->child_pipes[stream][stream == STDIN_FD ? 0 : 1]; + process_stream_handle* pipe = &self->child_pipes[stream][stream == STDIN_FD ? 0 : 1]; if (*pipe) { close_fd(pipe); } @@ -467,7 +628,7 @@ static int f_close_stream(lua_State* L) { static int process_strerror(lua_State* L) { #if _WIN32 return 1; - #endif + #endif int error_code = luaL_checknumber(L, 1); if (error_code < 0) lua_pushstring(L, strerror(error_code)); @@ -525,14 +686,37 @@ static int self_signal(lua_State* L, signal_e sig) { static int f_terminate(lua_State* L) { return self_signal(L, SIGNAL_TERM); } static int f_kill(lua_State* L) { return self_signal(L, SIGNAL_KILL); } static int f_interrupt(lua_State* L) { return self_signal(L, SIGNAL_INTERRUPT); } -static int f_gc(lua_State* L) { + +static int f_gc(lua_State* L) { process_t* self = (process_t*) luaL_checkudata(L, 1, API_TYPE_PROCESS); - if (!self->detached) + + if (poll_process(self, 0) && !self->detached) { + // attempt to kill the process if not detached + process_kill_t *p; + signal_process(self, SIGNAL_TERM); + p = malloc(sizeof(process_kill_t)); + if (!p || !kill_list_thread) { + // if we can't allocate, we'll use the old method + poll_process(self, PROCESS_TERM_DELAY); + if (self->running) { + signal_process(self, SIGNAL_KILL); + poll_process(self, PROCESS_TERM_DELAY); + } + } else { + // send the handle to a queue for asynchronous waiting + p->handle = PROCESS_GET_HANDLE(self); + p->start_time = SDL_GetTicks(); + p->tries = 1; + SDL_LockMutex(kill_list.mutex); + kill_list_push(&kill_list, p); + SDL_CondSignal(kill_list.has_work); + SDL_UnlockMutex(kill_list.mutex); + } + } close_fd(&self->child_pipes[STDIN_FD ][1]); close_fd(&self->child_pipes[STDOUT_FD][0]); - close_fd(&self->child_pipes[STDERR_FD][0]); - poll_process(self, 10); + close_fd(&self->child_pipes[STDERR_FD][0]); return 0; } @@ -542,11 +726,16 @@ static int f_running(lua_State* L) { return 1; } -static const struct luaL_Reg lib[] = { +static int process_gc(lua_State *L) { + kill_list_wait_all(&kill_list); + SDL_WaitThread(kill_list_thread, NULL); + kill_list_free(&kill_list); + return 0; +} + +static const struct luaL_Reg process_metatable[] = { {"__gc", f_gc}, {"__tostring", f_tostring}, - {"start", process_start}, - {"strerror", process_strerror}, {"pid", f_pid}, {"returncode", f_returncode}, {"read", f_read}, @@ -562,12 +751,29 @@ static const struct luaL_Reg lib[] = { {NULL, NULL} }; +static const struct luaL_Reg lib[] = { + { "start", process_start }, + { "strerror", process_strerror }, + { NULL, NULL } +}; + int luaopen_process(lua_State *L) { + if (kill_list_init(&kill_list)) + kill_list_thread = SDL_CreateThread(kill_list_worker, "process_kill", &kill_list); + + // create the process metatable luaL_newmetatable(L, API_TYPE_PROCESS); - luaL_setfuncs(L, lib, 0); + luaL_setfuncs(L, process_metatable, 0); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); + // create the process library + luaL_newlib(L, lib); + lua_newtable(L); + lua_pushcfunction(L, process_gc); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); + API_CONSTANT_DEFINE(L, -1, "WAIT_INFINITE", WAIT_INFINITE); API_CONSTANT_DEFINE(L, -1, "WAIT_DEADLINE", WAIT_DEADLINE); @@ -576,7 +782,7 @@ int luaopen_process(lua_State *L) { API_CONSTANT_DEFINE(L, -1, "STREAM_STDERR", STDERR_FD); API_CONSTANT_DEFINE(L, -1, "REDIRECT_DEFAULT", REDIRECT_DEFAULT); - API_CONSTANT_DEFINE(L, -1, "REDIRECT_STDOUT", STDOUT_FD); + API_CONSTANT_DEFINE(L, -1, "REDIRECT_STDOUT", STDOUT_FD); API_CONSTANT_DEFINE(L, -1, "REDIRECT_STDERR", STDERR_FD); API_CONSTANT_DEFINE(L, -1, "REDIRECT_PARENT", REDIRECT_PARENT); // Redirects to parent's STDOUT/STDERR API_CONSTANT_DEFINE(L, -1, "REDIRECT_DISCARD", REDIRECT_DISCARD); // Closes the filehandle, discarding it. diff --git a/src/main.c b/src/main.c index 174e4372..e3098c16 100644 --- a/src/main.c +++ b/src/main.c @@ -255,8 +255,10 @@ init_lua: goto init_lua; } - lua_close(L); + // This allows the window to be destroyed before lite-xl is done with + // reaping child processes ren_free_window_resources(&window_renderer); + lua_close(L); return EXIT_SUCCESS; } From bf35417f82f1f1c6591d473cda9f7631e54cb548 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Tue, 28 Mar 2023 01:17:11 +0200 Subject: [PATCH 045/148] Don't calculate widths per-uft8-char when not needed (#1409) --- data/core/docview.lua | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/data/core/docview.lua b/data/core/docview.lua index cdfb0298..908d7c6a 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -175,12 +175,21 @@ function DocView:get_col_x_offset(line, col) for _, type, text in self.doc.highlighter:each_token(line) do local font = style.syntax_fonts[type] or default_font if font ~= default_font then font:set_tab_size(indent_size) end - for char in common.utf8_chars(text) do - if column == col then + local length = #text + if column + length <= col then + xoffset = xoffset + font:get_width(text) + column = column + length + if column >= col then return xoffset end - xoffset = xoffset + font:get_width(char) - column = column + #char + else + for char in common.utf8_chars(text) do + if column >= col then + return xoffset + end + xoffset = xoffset + font:get_width(char) + column = column + #char + end end end @@ -198,14 +207,22 @@ function DocView:get_x_offset_col(line, x) for _, type, text in self.doc.highlighter:each_token(line) do local font = style.syntax_fonts[type] or default_font if font ~= default_font then font:set_tab_size(indent_size) end - for char in common.utf8_chars(text) do - local w = font:get_width(char) - if xoffset >= x then - return (xoffset - x > w / 2) and last_i or i + local width = font:get_width(text) + -- Don't take the shortcut if the width matches x, + -- because we need last_i which should be calculated using utf-8. + if xoffset + width < x then + xoffset = xoffset + width + i = i + #text + else + for char in common.utf8_chars(text) do + local w = font:get_width(char) + if xoffset >= x then + return (xoffset - x > w / 2) and last_i or i + end + xoffset = xoffset + w + last_i = i + i = i + #char end - xoffset = xoffset + w - last_i = i - i = i + #char end end From 6deca53303030457c1f6b3d2356311ae4b65b2bc Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 28 Mar 2023 19:57:24 -0400 Subject: [PATCH 046/148] Disable `trimwhitespace` and `drawwhitespace` via their configs (#1446) Instead of completely disabling them, we now use their internal toggle. Also moved `drawwhitespace` commands inside the plugin. --- * Fixed bug where commands would show even when plugin was disbled. Also removed antiquated way of disabling. * Fixed typos. * Also moved trimwhitespace out of config, if it already has a default enabled value of false. * Changed documentation. * Clarified comments. --- data/core/command.lua | 2 +- data/core/commands/drawwhitespace.lua | 16 ---------------- data/core/config.lua | 3 --- data/core/init.lua | 7 ++----- data/plugins/drawwhitespace.lua | 20 ++++++++++++++++++-- data/plugins/trimwhitespace.lua | 4 ++-- 6 files changed, 23 insertions(+), 29 deletions(-) delete mode 100644 data/core/commands/drawwhitespace.lua diff --git a/data/core/command.lua b/data/core/command.lua index f5738304..faf872e2 100644 --- a/data/core/command.lua +++ b/data/core/command.lua @@ -107,7 +107,7 @@ end function command.add_defaults() local reg = { "core", "root", "command", "doc", "findreplace", - "files", "drawwhitespace", "dialog", "log", "statusbar" + "files", "dialog", "log", "statusbar" } for _, name in ipairs(reg) do require("core.commands." .. name) diff --git a/data/core/commands/drawwhitespace.lua b/data/core/commands/drawwhitespace.lua deleted file mode 100644 index 9372c55d..00000000 --- a/data/core/commands/drawwhitespace.lua +++ /dev/null @@ -1,16 +0,0 @@ -local command = require "core.command" -local config = require "core.config" - -command.add(nil, { - ["draw-whitespace:toggle"] = function() - config.draw_whitespace = not config.draw_whitespace - end, - - ["draw-whitespace:disable"] = function() - config.draw_whitespace = false - end, - - ["draw-whitespace:enable"] = function() - config.draw_whitespace = true - end, -}) diff --git a/data/core/config.lua b/data/core/config.lua index fc5da98a..c1a16b11 100644 --- a/data/core/config.lua +++ b/data/core/config.lua @@ -101,8 +101,5 @@ setmetatable(config.plugins, { end }) --- Disable these plugins by default. -config.plugins.trimwhitespace = false -config.plugins.drawwhitespace = false return config diff --git a/data/core/init.lua b/data/core/init.lua index 8a1785c5..ca9f2f85 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -531,12 +531,9 @@ local style = require "core.style" ------------------------------ Plugins ---------------------------------------- --- enable or disable plugin loading setting config entries: +-- disable plugin loading setting config entries: --- enable plugins.trimwhitespace, otherwise it is disabled by default: --- config.plugins.trimwhitespace = true --- --- disable detectindent, otherwise it is enabled by default +-- disable plugin detectindent, otherwise it is enabled by default: -- config.plugins.detectindent = false ---------------------------- Miscellaneous ------------------------------------- diff --git a/data/plugins/drawwhitespace.lua b/data/plugins/drawwhitespace.lua index 89be875d..ef69107f 100644 --- a/data/plugins/drawwhitespace.lua +++ b/data/plugins/drawwhitespace.lua @@ -3,11 +3,12 @@ local style = require "core.style" local DocView = require "core.docview" local common = require "core.common" +local command = require "core.command" local config = require "core.config" local Highlighter = require "core.doc.highlighter" config.plugins.drawwhitespace = common.merge({ - enabled = true, + enabled = false, show_leading = true, show_trailing = true, show_middle = true, @@ -41,7 +42,7 @@ config.plugins.drawwhitespace = common.merge({ description = "Disable or enable the drawing of white spaces.", path = "enabled", type = "toggle", - default = true + default = false }, { label = "Show Leading", @@ -303,3 +304,18 @@ function DocView:draw_line_text(idx, x, y) return draw_line_text(self, idx, x, y) end + + +command.add(nil, { + ["draw-whitespace:toggle"] = function() + config.plugins.drawwhitespace.enabled = not config.drawwhitespace.enabled + end, + + ["draw-whitespace:disable"] = function() + config.plugins.drawwhitespace.enabled = false + end, + + ["draw-whitespace:enable"] = function() + config.plugins.drawwhitespace.enabled = true + end, +}) diff --git a/data/plugins/trimwhitespace.lua b/data/plugins/trimwhitespace.lua index 6fb67230..8daa77e0 100644 --- a/data/plugins/trimwhitespace.lua +++ b/data/plugins/trimwhitespace.lua @@ -8,7 +8,7 @@ local Doc = require "core.doc" ---@field enabled boolean ---@field trim_empty_end_lines boolean config.plugins.trimwhitespace = common.merge({ - enabled = true, + enabled = false, trim_empty_end_lines = false, config_spec = { name = "Trim Whitespace", @@ -17,7 +17,7 @@ config.plugins.trimwhitespace = common.merge({ description = "Disable or enable the trimming of white spaces by default.", path = "enabled", type = "toggle", - default = true + default = false }, { label = "Trim Empty End Lines", From 6d217204f6f28c926b743aafaa034eedf2487e13 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Sat, 1 Apr 2023 18:12:39 +0200 Subject: [PATCH 047/148] Allow `tokenizer` to pause and resume in the middle of a line (#1444) --- data/core/doc/highlighter.lua | 25 ++++++++++++++++-------- data/core/tokenizer.lua | 36 ++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/data/core/doc/highlighter.lua b/data/core/doc/highlighter.lua index 0cddb2c3..b1367049 100644 --- a/data/core/doc/highlighter.lua +++ b/data/core/doc/highlighter.lua @@ -19,25 +19,34 @@ function Highlighter:start() if self.running then return end self.running = true core.add_thread(function() - while self.first_invalid_line < self.max_wanted_line do + while self.first_invalid_line <= self.max_wanted_line do local max = math.min(self.first_invalid_line + 40, self.max_wanted_line) local retokenized_from for i = self.first_invalid_line, max do local state = (i > 1) and self.lines[i - 1].state local line = self.lines[i] - if not (line and line.init_state == state and line.text == self.doc.lines[i]) then + if line and line.resume and (line.init_state ~= state or line.text ~= self.doc.lines[i]) then + -- Reset the progress if no longer valid + line.resume = nil + end + if not (line and line.init_state == state and line.text == self.doc.lines[i] and not line.resume) then retokenized_from = retokenized_from or i - self.lines[i] = self:tokenize_line(i, state) + self.lines[i] = self:tokenize_line(i, state, line and line.resume) + if self.lines[i].resume then + self.first_invalid_line = i + goto yield + end elseif retokenized_from then self:update_notify(retokenized_from, i - retokenized_from - 1) retokenized_from = nil end end + + self.first_invalid_line = max + 1 + ::yield:: if retokenized_from then self:update_notify(retokenized_from, max - retokenized_from) end - - self.first_invalid_line = max + 1 core.redraw = true coroutine.yield() end @@ -48,7 +57,7 @@ end local function set_max_wanted_lines(self, amount) self.max_wanted_line = amount - if self.first_invalid_line < self.max_wanted_line then + if self.first_invalid_line <= self.max_wanted_line then self:start() end end @@ -91,11 +100,11 @@ function Highlighter:update_notify(line, n) end -function Highlighter:tokenize_line(idx, state) +function Highlighter:tokenize_line(idx, state, resume) local res = {} res.init_state = state res.text = self.doc.lines[idx] - res.tokens, res.state = tokenizer.tokenize(self.doc.syntax, res.text, state) + res.tokens, res.state, res.resume = tokenizer.tokenize(self.doc.syntax, res.text, state, resume) return res end diff --git a/data/core/tokenizer.lua b/data/core/tokenizer.lua index b2126124..6d99d9c4 100644 --- a/data/core/tokenizer.lua +++ b/data/core/tokenizer.lua @@ -1,5 +1,6 @@ local core = require "core" local syntax = require "core.syntax" +local config = require "core.config" local tokenizer = {} local bad_patterns = {} @@ -8,7 +9,7 @@ local function push_token(t, type, text) type = type or "normal" local prev_type = t[#t-1] local prev_text = t[#t] - if prev_type and (prev_type == type or prev_text:ufind("^%s*$")) then + if prev_type and (prev_type == type or (prev_text:ufind("^%s*$") and type ~= "incomplete")) then t[#t-1] = type t[#t] = prev_text .. text else @@ -128,8 +129,8 @@ end ---@param incoming_syntax table ---@param text string ---@param state string -function tokenizer.tokenize(incoming_syntax, text, state) - local res = {} +function tokenizer.tokenize(incoming_syntax, text, state, resume) + local res local i = 1 if #incoming_syntax.patterns == 0 then @@ -137,6 +138,20 @@ function tokenizer.tokenize(incoming_syntax, text, state) end state = state or string.char(0) + + if resume then + res = resume.res + -- Remove "incomplete" tokens + while res[#res-1] == "incomplete" do + table.remove(res, #res) + table.remove(res, #res) + end + i = resume.i + state = resume.state + end + + res = res or {} + -- incoming_syntax : the parent syntax of the file. -- state : a string of bytes representing syntax state (see above) @@ -245,7 +260,22 @@ function tokenizer.tokenize(incoming_syntax, text, state) end local text_len = text:ulen() + local start_time = system.get_time() + local starting_i = i while i <= text_len do + -- Every 200 chars, check if we're out of time + if i - starting_i > 200 then + starting_i = i + if system.get_time() - start_time > 0.5 / config.fps then + -- We're out of time + push_token(res, "incomplete", string.usub(text, i)) + return res, string.char(0), { + res = res, + i = i, + state = state + } + end + end -- continue trying to match the end pattern of a pair if we have a state set if current_pattern_idx > 0 then local p = current_syntax.patterns[current_pattern_idx] From 12e0634f9c9f45eb15e9fc65ed9d73519c895dd5 Mon Sep 17 00:00:00 2001 From: vqn <85911372+vqns@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:54:00 +0000 Subject: [PATCH 048/148] fix cursors positions when deleting multiple selections (#1393) * correctly handle overlapping selections merge cursors in Doc:raw_remove --- data/core/commands/doc.lua | 4 ++-- data/core/doc/init.lua | 48 +++++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index ebaf698c..eca876ea 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -323,7 +323,7 @@ local commands = { end, ["doc:delete"] = function(dv) - for idx, line1, col1, line2, col2 in dv.doc:get_selections() do + for idx, line1, col1, line2, col2 in dv.doc:get_selections(true, true) do if line1 == line2 and col1 == col2 and dv.doc.lines[line1]:find("^%s*$", col1) then dv.doc:remove(line1, col1, line1, math.huge) end @@ -333,7 +333,7 @@ local commands = { ["doc:backspace"] = function(dv) local _, indent_size = dv.doc:get_indent_info() - for idx, line1, col1, line2, col2 in dv.doc:get_selections() do + for idx, line1, col1, line2, col2 in dv.doc:get_selections(true, true) do if line1 == line2 and col1 == col2 then local text = dv.doc:get_text(line1, 1, line1, col1) if #text >= indent_size and text:find("^ *$") then diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index 26fc2a52..7fdd896c 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -427,19 +427,51 @@ function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time) local before = self.lines[line1]:sub(1, col1 - 1) local after = self.lines[line2]:sub(col2) - -- splice line into line array - common.splice(self.lines, line1, line2 - line1 + 1, { before .. after }) + local line_removal = line2 - line1 + local col_removal = col2 - col1 - -- move all cursors back if they share a line with the removed text + -- splice line into line array + common.splice(self.lines, line1, line_removal + 1, { before .. after }) + + local merge = false + + -- keep selections in correct positions: each pair (line, col) + -- * remains unchanged if before the deleted text + -- * is set to (line1, col1) if in the deleted text + -- * is set to (line1, col - col_removal) if on line2 but out of the deleted text + -- * is set to (line - line_removal, col) if after line2 for idx, cline1, ccol1, cline2, ccol2 in self:get_selections(true, true) do - if cline1 < line2 then break end - local line_removal = line2 - line1 - local column_removal = line2 == cline2 and col2 < ccol1 and (line2 == line1 and col2 - col1 or col2) or 0 - self:set_selections(idx, cline1 - line_removal, ccol1 - column_removal, cline2 - line_removal, ccol2 - column_removal) + if cline2 < line1 then break end + local l1, c1, l2, c2 = cline1, ccol1, cline2, ccol2 + + if cline1 > line1 or (cline1 == line1 and ccol1 > col1) then + if cline1 > line2 then + l1 = l1 - line_removal + else + l1 = line1 + c1 = (cline1 == line2 and ccol1 > col2) and c1 - col_removal or col1 + end + end + + if cline2 > line1 or (cline2 == line2 and ccol2 > col1) then + if cline2 > line2 then + l2 = l2 - line_removal + else + l2 = line1 + c2 = (cline2 == line2 and ccol2 > col2) and c2 - col_removal or col1 + end + end + + if l1 == line1 and c1 == col1 then merge = true end + self:set_selections(idx, l1, c1, l2, c2) + end + + if merge then + self:merge_cursors() end -- update highlighter and assure selection is in bounds - self.highlighter:remove_notify(line1, line2 - line1) + self.highlighter:remove_notify(line1, line_removal) self:sanitize_selection() end From a24432941c502d618049eacf0b274439b06cf39b Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sat, 8 Apr 2023 01:06:01 +0800 Subject: [PATCH 049/148] Fix invalid EXEFILE and EXEDIR on Windows (#1396) * fix(main): fix get_exe_filename returning invalid result on Windows * fix(main): fix bootstrap not intepreting UTF-8 properly --- src/main.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index e3098c16..01164312 100644 --- a/src/main.c +++ b/src/main.c @@ -32,8 +32,18 @@ static double get_scale(void) { static void get_exe_filename(char *buf, int sz) { #if _WIN32 - int len = GetModuleFileName(NULL, buf, sz - 1); - buf[len] = '\0'; + int len; + wchar_t *buf_w = malloc(sizeof(wchar_t) * sz); + if (buf_w) { + len = GetModuleFileNameW(NULL, buf_w, sz - 1); + buf_w[len] = L'\0'; + // if the conversion failed we'll empty the string + if (!WideCharToMultiByte(CP_UTF8, 0, buf_w, -1, buf, sz, NULL, NULL)) + buf[0] = '\0'; + free(buf_w); + } else { + buf[0] = '\0'; + } #elif __linux__ char path[] = "/proc/self/exe"; ssize_t len = readlink(path, buf, sz - 1); @@ -216,9 +226,10 @@ init_lua: const char *init_lite_code = \ "local core\n" "xpcall(function()\n" + " local match = require('utf8extra').match\n" " HOME = os.getenv('" LITE_OS_HOME "')\n" - " local exedir = EXEFILE:match('^(.*)" LITE_PATHSEP_PATTERN LITE_NONPATHSEP_PATTERN "$')\n" - " local prefix = exedir:match('^(.*)" LITE_PATHSEP_PATTERN "bin$')\n" + " local exedir = match(EXEFILE, '^(.*)" LITE_PATHSEP_PATTERN LITE_NONPATHSEP_PATTERN "$')\n" + " local prefix = match(exedir, '^(.*)" LITE_PATHSEP_PATTERN "bin$')\n" " dofile((MACOS_RESOURCES or (prefix and prefix .. '/share/lite-xl' or exedir .. '/data')) .. '/core/start.lua')\n" " core = require(os.getenv('LITE_XL_RUNTIME') or 'core')\n" " core.init()\n" From bb31a1adf2bce0bab055f3f14932c25b62dc5469 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sat, 8 Apr 2023 01:11:01 +0800 Subject: [PATCH 050/148] fix(windows-utf8-patch): fix os.getenv() not supporting UTF-8 output (#1397) --- resources/windows/001-lua-unicode.diff | 64 +++++++++++++++++++------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/resources/windows/001-lua-unicode.diff b/resources/windows/001-lua-unicode.diff index 7785b8ea..31fec364 100644 --- a/resources/windows/001-lua-unicode.diff +++ b/resources/windows/001-lua-unicode.diff @@ -1,6 +1,6 @@ -diff -ruN lua-5.4.4/meson.build lua-5.4.4-mod/meson.build ---- lua-5.4.4/meson.build 2022-11-16 10:33:38.424383300 +0800 -+++ lua-5.4.4-mod/meson.build 2022-11-16 09:40:57.697918000 +0800 +diff -ruN lua-5.4.4\meson.build lua-5.4.4-patched\meson.build +--- lua-5.4.4\meson.build Wed Feb 22 18:16:56 2023 ++++ lua-5.4.4-patched\meson.build Wed Feb 22 04:10:01 2023 @@ -85,6 +85,7 @@ 'src/lutf8lib.c', 'src/lvm.c', @@ -9,9 +9,9 @@ diff -ruN lua-5.4.4/meson.build lua-5.4.4-mod/meson.build dependencies: lua_lib_deps, version: meson.project_version(), soversion: lua_versions[0] + '.' + lua_versions[1], -diff -ruN lua-5.4.4/src/luaconf.h lua-5.4.4-mod/src/luaconf.h ---- lua-5.4.4/src/luaconf.h 2022-01-13 19:24:43.000000000 +0800 -+++ lua-5.4.4-mod/src/luaconf.h 2022-11-16 09:40:57.703926000 +0800 +diff -ruN lua-5.4.4\src\luaconf.h lua-5.4.4-patched\src\luaconf.h +--- lua-5.4.4\src\luaconf.h Thu Jan 13 19:24:43 2022 ++++ lua-5.4.4-patched\src\luaconf.h Wed Feb 22 04:10:02 2023 @@ -782,5 +782,15 @@ @@ -28,9 +28,9 @@ diff -ruN lua-5.4.4/src/luaconf.h lua-5.4.4-mod/src/luaconf.h + #endif -diff -ruN lua-5.4.4/src/Makefile lua-5.4.4-mod/src/Makefile ---- lua-5.4.4/src/Makefile 2021-07-15 22:01:52.000000000 +0800 -+++ lua-5.4.4-mod/src/Makefile 2022-11-16 09:40:57.708921800 +0800 +diff -ruN lua-5.4.4\src\Makefile lua-5.4.4-patched\src\Makefile +--- lua-5.4.4\src\Makefile Thu Jul 15 22:01:52 2021 ++++ lua-5.4.4-patched\src\Makefile Wed Feb 22 04:10:02 2023 @@ -33,7 +33,7 @@ PLATS= guess aix bsd c89 freebsd generic linux linux-readline macosx mingw posix solaris @@ -40,10 +40,10 @@ diff -ruN lua-5.4.4/src/Makefile lua-5.4.4-mod/src/Makefile LIB_O= lauxlib.o lbaselib.o lcorolib.o ldblib.o liolib.o lmathlib.o loadlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o linit.o BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) -diff -ruN lua-5.4.4/src/utf8_wrappers.c lua-5.4.4-mod/src/utf8_wrappers.c ---- lua-5.4.4/src/utf8_wrappers.c 1970-01-01 07:30:00.000000000 +0730 -+++ lua-5.4.4-mod/src/utf8_wrappers.c 2022-11-16 10:09:04.583866600 +0800 -@@ -0,0 +1,101 @@ +diff -ruN lua-5.4.4\src\utf8_wrappers.c lua-5.4.4-patched\src\utf8_wrappers.c +--- lua-5.4.4\src\utf8_wrappers.c Thu Jan 01 08:00:00 1970 ++++ lua-5.4.4-patched\src\utf8_wrappers.c Wed Feb 22 18:13:45 2023 +@@ -0,0 +1,129 @@ +/** + * Wrappers to provide Unicode (UTF-8) support on Windows. + * @@ -58,12 +58,17 @@ diff -ruN lua-5.4.4/src/utf8_wrappers.c lua-5.4.4-mod/src/utf8_wrappers.c +#include +#include + ++// A environment variable has the maximum length of 32767 characters ++// including the terminator. ++#define MAX_ENV_SIZE 32767 +// Set a high limit in case long paths are enabled. +#define MAX_PATH_SIZE 4096 +#define MAX_MODE_SIZE 128 +// cmd.exe argument length is reportedly limited to 8192. +#define MAX_CMD_SIZE 8192 + ++static char env_value[MAX_ENV_SIZE]; ++ +FILE *fopen_utf8(const char *pathname, const char *mode) { + wchar_t pathname_w[MAX_PATH_SIZE]; + wchar_t mode_w[MAX_MODE_SIZE]; @@ -144,11 +149,34 @@ diff -ruN lua-5.4.4/src/utf8_wrappers.c lua-5.4.4-mod/src/utf8_wrappers.c + } + return LoadLibraryExW(pathname_w, hFile, dwFlags); +} ++ ++char* getenv_utf8(const char *varname) { ++ /** This implementation is not thread safe. ++ * The string is only valid until the next call to getenv. ++ * This behavior is allowed per POSIX.1-2017 where it was said that: ++ * > The returned string pointer might be invalidated or the string content might be overwritten by a subsequent call to getenv(), setenv(), unsetenv(), or (if supported) putenv() but they shall not be affected by a call to any other function in this volume of POSIX.1-2017. ++ * > The returned string pointer might also be invalidated if the calling thread is terminated. ++ * > The getenv() function need not be thread-safe. ++ */ ++ wchar_t *value_w; ++ wchar_t varname_w[MAX_ENV_SIZE]; ++ ++ if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, varname, -1, varname_w, MAX_ENV_SIZE)) ++ return NULL; ++ value_w = _wgetenv((const wchar_t *) varname_w); ++ if (!value_w) ++ return NULL; ++ ++ if (!WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, value_w, -1, env_value, MAX_ENV_SIZE, NULL, NULL)) ++ return NULL; ++ ++ return env_value; ++} +#endif -diff -ruN lua-5.4.4/src/utf8_wrappers.h lua-5.4.4-mod/src/utf8_wrappers.h ---- lua-5.4.4/src/utf8_wrappers.h 1970-01-01 07:30:00.000000000 +0730 -+++ lua-5.4.4-mod/src/utf8_wrappers.h 2022-11-16 10:29:46.044102000 +0800 -@@ -0,0 +1,44 @@ +diff -ruN lua-5.4.4\src\utf8_wrappers.h lua-5.4.4-patched\src\utf8_wrappers.h +--- lua-5.4.4\src\utf8_wrappers.h Thu Jan 01 08:00:00 1970 ++++ lua-5.4.4-patched\src\utf8_wrappers.h Wed Feb 22 18:09:48 2023 +@@ -0,0 +1,46 @@ +/** + * Wrappers to provide Unicode (UTF-8) support on Windows. + * @@ -180,9 +208,11 @@ diff -ruN lua-5.4.4/src/utf8_wrappers.h lua-5.4.4-mod/src/utf8_wrappers.h +int remove_utf8(const char *pathname); +int rename_utf8(const char *oldpath, const char *newpath); +int system_utf8(const char *command); ++char *getenv_utf8(const char *varname); +#define remove remove_utf8 +#define rename rename_utf8 +#define system system_utf8 ++#define getenv getenv_utf8 +#endif + +#ifdef loadlib_c From 4e3d6824ff18128044f7b06cb77782c1b7fb4ed0 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sat, 8 Apr 2023 01:18:16 +0800 Subject: [PATCH 051/148] fix: fix differing stacktrace on stdout and file (#1404) * fix(c-bootstrap): produce identical stack traces --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 01164312..c068421b 100644 --- a/src/main.c +++ b/src/main.c @@ -237,7 +237,7 @@ init_lua: "end, function(err)\n" " local error_dir\n" " io.stdout:write('Error: '..tostring(err)..'\\n')\n" - " io.stdout:write(debug.traceback(nil, 4)..'\\n')\n" + " io.stdout:write(debug.traceback(nil, 2)..'\\n')\n" " if core and core.on_error then\n" " error_dir=USERDIR\n" " pcall(core.on_error, err)\n" From a0c8f01312730684c614e25d8b701dc43ae79747 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sat, 8 Apr 2023 01:24:27 +0800 Subject: [PATCH 052/148] fix(CI): bump dependency versions (#1434) * refactor(ci): use microsoft/setup-msbuild * fix(ci): fix wrong option name for setup-msbuild * fix(ci): bump setup-python version * fix(lua-utf8-patch): enable support for windows vista and above * fix(ci): use vs backend * fix(ci): reconfigure project manually after patch * fix(ci): add a separate build step * fix(ci): use msvc-dev-cmd again --- .github/workflows/build.yml | 33 ++++++++++++++++++--------------- .github/workflows/release.yml | 12 ++++++------ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8fb880ff..a3cbb2a4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,9 +30,9 @@ jobs: echo "$HOME/.local/bin" >> "$GITHUB_PATH" echo "INSTALL_REF=${GITHUB_REF##*/}" >> "$GITHUB_ENV" echo "INSTALL_NAME=lite-xl-${GITHUB_REF##*/}-linux-$(uname -m)-portable" >> "$GITHUB_ENV" - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Python Setup - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.9 - name: Update Packages @@ -47,7 +47,7 @@ jobs: if: ${{ matrix.config.cc == 'gcc' }} run: bash scripts/package.sh --version ${INSTALL_REF} --debug --binary - name: Upload Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: ${{ matrix.config.cc == 'gcc' }} with: name: Linux Artifacts @@ -71,9 +71,9 @@ jobs: echo "$HOME/.local/bin" >> "$GITHUB_PATH" echo "INSTALL_REF=${GITHUB_REF##*/}" >> "$GITHUB_ENV" echo "INSTALL_NAME=lite-xl-${GITHUB_REF##*/}-macos-$(uname -m)" >> "$GITHUB_ENV" - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Python Setup - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.9 - name: Install Dependencies @@ -85,7 +85,7 @@ jobs: - name: Create DMG Image run: bash scripts/package.sh --version ${INSTALL_REF} --debug --dmg - name: Upload DMG Image - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: macOS DMG Image path: ${{ env.INSTALL_NAME }}.dmg @@ -100,7 +100,7 @@ jobs: run: shell: msys2 {0} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} @@ -127,7 +127,7 @@ jobs: - name: Package run: bash scripts/package.sh --version ${INSTALL_REF} --debug --binary - name: Upload Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Windows Artifacts path: ${{ env.INSTALL_NAME }}.zip @@ -137,20 +137,22 @@ jobs: runs-on: windows-2019 strategy: matrix: - arch: [amd64, amd64_x86] + arch: + - { target: x86, name: i686 } + - { target: x64, name: x86_64 } steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: ilammy/msvc-dev-cmd@v1 with: - arch: ${{ matrix.arch }} - - uses: actions/setup-python@v1 + arch: ${{ matrix.arch.target }} + - uses: actions/setup-python@v2 with: python-version: '3.x' - name: Install meson and ninja run: pip install meson ninja - name: Set up environment variables run: | - "INSTALL_NAME=lite-xl-$($env:GITHUB_REF -replace ".*/")-windows-msvc-${{ matrix.arch }}" >> $env:GITHUB_ENV + "INSTALL_NAME=lite-xl-$($env:GITHUB_REF -replace ".*/")-windows-msvc-${{ matrix.arch.name }}" >> $env:GITHUB_ENV "INSTALL_REF=$($env:GITHUB_REF -replace ".*/")" >> $env:GITHUB_ENV "LUA_SUBPROJECT_PATH=subprojects/lua-5.4.4" >> $env:GITHUB_ENV - name: Configure @@ -158,13 +160,14 @@ jobs: meson setup --wrap-mode=forcefallback build Get-Content -Path resources/windows/001-lua-unicode.diff -Raw | patch -d $env:LUA_SUBPROJECT_PATH -p1 --forward - name: Build - run: meson install -C build --destdir="../lite-xl" + run: | + meson install -C build --destdir="../lite-xl" - name: Package run: | Remove-Item -Recurse -Force -Path "lite-xl/lib","lite-xl/include" Compress-Archive -Path lite-xl -DestinationPath "$env:INSTALL_NAME.zip" - name: Upload Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Windows Artifacts (MSVC) path: ${{ env.INSTALL_NAME }}.zip diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea0e1848..47b826dd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: version: ${{ steps.tag.outputs.version }} steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Fetch Version id: tag run: | @@ -58,9 +58,9 @@ jobs: run: | echo "$HOME/.local/bin" >> "$GITHUB_PATH" echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Python Setup - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.9 - name: Update Packages @@ -115,9 +115,9 @@ jobs: echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" echo "INSTALL_NAME=lite-xl-${{ needs.release.outputs.version }}-macos-${{ matrix.arch }}" >> "$GITHUB_ENV" echo "INSTALL_NAME_ADDONS=lite-xl-${{ needs.release.outputs.version }}-addons-macos-${{ matrix.arch }}" >> "$GITHUB_ENV" - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Python Setup - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.9 - name: Install Dependencies @@ -150,7 +150,7 @@ jobs: run: shell: msys2 {0} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} From 84aeea61c29d01167bcfef132d3be89a7e115353 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sat, 8 Apr 2023 01:25:31 +0800 Subject: [PATCH 053/148] Optimizing MSYS2 CI (#1435) * feat(ci): install dependencies on setup * fix(ci): don't update msys2 when setup * fix(ci): download subprojects before patching * doc(ci): document why meson subprojects download is called --- .github/workflows/build.yml | 18 ++++++++++++++---- scripts/build.sh | 15 ++++++++++----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a3cbb2a4..12247bfb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -95,7 +95,9 @@ jobs: runs-on: windows-2019 strategy: matrix: - msystem: [MINGW32, MINGW64] + config: + - {msystem: MINGW32, arch: i686} + - {msystem: MINGW64, arch: x86_64} defaults: run: shell: msys2 {0} @@ -103,12 +105,16 @@ jobs: - uses: actions/checkout@v3 - uses: msys2/setup-msys2@v2 with: - msystem: ${{ matrix.msystem }} - update: true + msystem: ${{ matrix.config.msystem }} install: >- base-devel git zip + mingw-w64-${{ matrix.config.arch }}-gcc + mingw-w64-${{ matrix.config.arch }}-meson + mingw-w64-${{ matrix.config.arch }}-ninja + mingw-w64-${{ matrix.config.arch }}-ca-certificates + mingw-w64-${{ matrix.config.arch }}-ntldd - name: Set Environment Variables run: | echo "$HOME/.local/bin" >> "$GITHUB_PATH" @@ -119,6 +125,7 @@ jobs: echo "INSTALL_NAME=lite-xl-${GITHUB_REF##*/}-windows-i686" >> "$GITHUB_ENV" fi - name: Install Dependencies + if: false run: bash scripts/install-dependencies.sh --debug - name: Build run: | @@ -157,8 +164,11 @@ jobs: "LUA_SUBPROJECT_PATH=subprojects/lua-5.4.4" >> $env:GITHUB_ENV - name: Configure run: | - meson setup --wrap-mode=forcefallback build + # Download the subprojects first so we can patch it before configuring. + # This avoids reconfiguring the subprojects when compiling. + meson subprojects download Get-Content -Path resources/windows/001-lua-unicode.diff -Raw | patch -d $env:LUA_SUBPROJECT_PATH -p1 --forward + meson setup --wrap-mode=forcefallback build - name: Build run: | meson install -C build --destdir="../lite-xl" diff --git a/scripts/build.sh b/scripts/build.sh index 82eb95f0..0cd4e8d8 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -124,6 +124,16 @@ main() { rm -rf "${build_dir}" + if [[ $patch_lua == "true" ]] && [[ ! -z $force_fallback ]]; then + # download the subprojects so we can start patching before configure. + # this will prevent reconfiguring the project. + meson subprojects download + lua_subproject_path=$(echo subprojects/lua-*/) + if [[ -d $lua_subproject_path ]]; then + patch -d $lua_subproject_path -p1 --forward < resources/windows/001-lua-unicode.diff + fi + fi + CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS meson setup \ --buildtype=$build_type \ --prefix "$prefix" \ @@ -134,11 +144,6 @@ main() { $pgo \ "${build_dir}" - lua_subproject_path=$(echo subprojects/lua-*/) - if [[ $patch_lua == "true" ]] && [[ ! -z $force_fallback ]] && [[ -d $lua_subproject_path ]]; then - patch -d $lua_subproject_path -p1 --forward < resources/windows/001-lua-unicode.diff - fi - meson compile -C "${build_dir}" if [[ $pgo != "" ]]; then From fdd6ca3426f832a0c514fd1f6a7de41bb0ea7b99 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sat, 8 Apr 2023 01:45:28 +0800 Subject: [PATCH 054/148] Update api_require to expose more symbols (#1437) * feat(system): update api_require for more symbols * fix(system): fix missing 5.1 symbols * fix(system): add more missing symbols * fix(system): add all symbols We got'em this time. I swear. * fix(system): fix undefined symbols due to conditional compilation There is only pain and suffering. Turns out some of the symbols are only exported when the options are enabled. We need to preprocess the header. --- src/api/system.c | 93 ++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/src/api/system.c b/src/api/system.c index ad7cede8..c7eb3897 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -913,47 +913,70 @@ typedef struct lua_function_node { #define P(FUNC) { "lua_" #FUNC, (fptr)(lua_##FUNC) } #define U(FUNC) { "luaL_" #FUNC, (fptr)(luaL_##FUNC) } +#define S(FUNC) { #FUNC, (fptr)(FUNC) } static void* api_require(const char* symbol) { static const lua_function_node nodes[] = { - P(atpanic), P(checkstack), - P(close), P(concat), P(copy), P(createtable), P(dump), - P(error), P(gc), P(getallocf), P(getfield), - P(gethook), P(gethookcount), P(gethookmask), P(getinfo), P(getlocal), - P(getmetatable), P(getstack), P(gettable), P(gettop), P(getupvalue), - P(isnumber), P(isstring), P(isuserdata), - P(load), P(newstate), P(newthread), P(next), + #if LUA_VERSION_NUM == 501 && LUA_VERSION_NUM == 502 && LUA_VERSION_NUM == 503 && LUA_VERSION_NUM == 504 + U(addlstring), U(addstring), U(addvalue), U(argerror), U(buffinit), + U(callmeta), U(checkany), U(checkinteger), U(checklstring), + U(checknumber), U(checkoption), U(checkstack), U(checktype), + U(checkudata), U(error), U(getmetafield), U(gsub), U(loadstring), + U(newmetatable), U(newstate), U(openlibs), U(optinteger), U(optlstring), + U(optnumber), U(pushresult), U(ref), U(unref), U(where), P(atpanic), + P(checkstack), P(close), P(concat), P(createtable), P(dump), P(error), + P(gc), P(getallocf), P(getfield), P(gethook), P(gethookcount), + P(gethookmask), P(getinfo), P(getlocal), P(getmetatable), P(getstack), + P(gettable), P(gettop), P(getupvalue), P(iscfunction), P(isnumber), + P(isstring), P(isuserdata), P(load), P(newstate), P(newthread), P(next), P(pushboolean), P(pushcclosure), P(pushfstring), P(pushinteger), P(pushlightuserdata), P(pushlstring), P(pushnil), P(pushnumber), - P(pushstring), P(pushthread), P(pushvalue), - P(pushvfstring), P(rawequal), P(rawget), P(rawgeti), - P(rawset), P(rawseti), P(resume), - P(setallocf), P(setfield), P(sethook), P(setlocal), - P(setmetatable), P(settable), P(settop), P(setupvalue), - P(status), P(tocfunction), P(tointegerx), P(tolstring), P(toboolean), - P(tonumberx), P(topointer), P(tothread), P(touserdata), - P(type), P(typename), P(upvalueid), P(upvaluejoin), P(version), P(xmove), - U(getmetafield), U(callmeta), U(argerror), U(checknumber), U(optnumber), - U(checkinteger), U(checkstack), U(checktype), U(checkany), - U(newmetatable), U(setmetatable), U(testudata), U(checkudata), U(where), - U(error), U(fileresult), U(execresult), U(ref), U(unref), U(loadstring), - U(newstate), U(setfuncs), U(buffinit), U(addlstring), U(addstring), - U(addvalue), U(pushresult), U(openlibs), {"api_load_libs", (void*)(api_load_libs)}, - #if LUA_VERSION_NUM >= 502 - P(absindex), P(arith), P(callk), P(compare), P(getglobal), - P(len), P(pcallk), P(rawgetp), P(rawlen), P(rawsetp), P(setglobal), - P(iscfunction), P(yieldk), - U(checkversion_), U(tolstring), U(len), U(getsubtable), U(prepbuffsize), - U(pushresultsize), U(buffinitsize), U(checklstring), U(checkoption), U(gsub), U(loadbufferx), - U(loadfilex), U(optinteger), U(optlstring), U(requiref), U(traceback), - #else - P(objlen), + P(pushstring), P(pushthread), P(pushvalue), P(pushvfstring), P(rawequal), + P(rawget), P(rawgeti), P(rawset), P(rawseti), P(resume), P(setallocf), + P(setfield), P(sethook), P(setlocal), P(setmetatable), P(settable), + P(settop), P(setupvalue), P(status), P(toboolean), P(tocfunction), + P(tolstring), P(topointer), P(tothread), P(touserdata), P(type), + P(typename), P(xmove), S(luaopen_base), S(luaopen_debug), S(luaopen_io), + S(luaopen_math), S(luaopen_os), S(luaopen_package), S(luaopen_string), + S(luaopen_table), S(api_load_libs), #endif - #if LUA_VERSION_NUM >= 504 - P(newuserdatauv), P(setiuservalue), P(getiuservalue) - #else - P(newuserdata), P(setuservalue), P(getuservalue) + #if LUA_VERSION_NUM == 502 && LUA_VERSION_NUM == 503 && LUA_VERSION_NUM == 504 + U(buffinitsize), U(checkversion_), U(execresult), U(fileresult), + U(getsubtable), U(len), U(loadbufferx), U(loadfilex), U(prepbuffsize), + U(pushresultsize), U(requiref), U(setfuncs), U(setmetatable), + U(testudata), U(tolstring), U(traceback), P(absindex), P(arith), + P(callk), P(compare), P(copy), P(getglobal), P(len), P(pcallk), + P(rawgetp), P(rawlen), P(rawsetp), P(setglobal), P(tointegerx), + P(tonumberx), P(upvalueid), P(upvaluejoin), P(version), P(yieldk), + S(luaopen_coroutine), + #endif + #if LUA_VERSION_NUM == 501 && LUA_VERSION_NUM == 502 && LUA_VERSION_NUM == 503 + P(newuserdata), + #endif + #if LUA_VERSION_NUM == 503 && LUA_VERSION_NUM == 504 + P(geti), P(isinteger), P(isyieldable), P(rotate), P(seti), + P(stringtonumber), S(luaopen_utf8), + #endif + #if LUA_VERSION_NUM == 502 && LUA_VERSION_NUM == 503 + P(getuservalue), P(setuservalue), S(luaopen_bit32), + #endif + #if LUA_VERSION_NUM == 501 && LUA_VERSION_NUM == 502 + P(insert), P(remove), P(replace), + #endif + #if LUA_VERSION_NUM == 504 + U(addgsub), U(typeerror), P(closeslot), P(getiuservalue), + P(newuserdatauv), P(resetthread), P(setcstacklimit), P(setiuservalue), + P(setwarnf), P(toclose), P(warning), + #endif + #if LUA_VERSION_NUM == 502 + U(checkunsigned), U(optunsigned), P(getctx), P(pushunsigned), + P(tounsignedx), + #endif + #if LUA_VERSION_NUM == 501 + U(findtable), U(loadbuffer), U(loadfile), U(openlib), U(prepbuffer), + U(register), U(typerror), P(call), P(cpcall), P(equal), P(getfenv), + P(lessthan), P(objlen), P(pcall), P(setfenv), P(setlevel), P(tointeger), + P(tonumber), P(yield), #endif - }; for (size_t i = 0; i < sizeof(nodes) / sizeof(lua_function_node); ++i) { if (strcmp(nodes[i].symbol, symbol) == 0) From d497402c30636cc64db6148a587d9f88b2c04fee Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 7 Apr 2023 20:41:32 +0200 Subject: [PATCH 055/148] Make `system.path_compare` more case-aware (#1457) * Use Lua-provided string lengths for `system.path_compare` * Make `system.path_compare` more case-aware Before, strings like `README.md` would be sorted before `changelog.md`, because we only looked at the raw ascii values. Now the character case is considered as a secondary sorting key. --- src/api/system.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/api/system.c b/src/api/system.c index c7eb3897..33e5c6c3 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -1044,11 +1044,11 @@ static int f_load_native_plugin(lua_State *L) { order used in the TreeView view of the project's files. Returns true iff path1 < path2 in the TreeView order. */ static int f_path_compare(lua_State *L) { - const char *path1 = luaL_checkstring(L, 1); + size_t len1, len2; + const char *path1 = luaL_checklstring(L, 1, &len1); const char *type1_s = luaL_checkstring(L, 2); - const char *path2 = luaL_checkstring(L, 3); + const char *path2 = luaL_checklstring(L, 3, &len2); const char *type2_s = luaL_checkstring(L, 4); - const int len1 = strlen(path1), len2 = strlen(path2); int type1 = strcmp(type1_s, "dir") != 0; int type2 = strcmp(type2_s, "dir") != 0; /* Find the index of the common part of the path. */ @@ -1073,17 +1073,34 @@ static int f_path_compare(lua_State *L) { return 1; } /* If types are the same compare the files' path alphabetically. */ - int cfr = 0; + int cfr = -1; int len_min = (len1 < len2 ? len1 : len2); + bool same_len = len1 == len2; for (int j = offset; j <= len_min; j++) { - if (path1[j] == path2[j]) continue; if (path1[j] == 0 || path2[j] == 0) { - cfr = (path1[j] == 0); + if (cfr < 0) cfr = 0; // The strings are equal + if (!same_len) { + cfr = (path1[j] == 0); + } + } else if (path1[j] == path2[j]) { + continue; } else if (path1[j] == PATHSEP || path2[j] == PATHSEP) { /* For comparison we treat PATHSEP as if it was the string terminator. */ cfr = (path1[j] == PATHSEP); } else { - cfr = (path1[j] < path2[j]); + char a = path1[j], b = path2[j]; + if (a >= 'A' && a <= 'Z') a += 32; + if (b >= 'A' && b <= 'Z') b += 32; + if (a == b) { + /* If the strings have the same length, we need + to keep the first case sensitive difference. */ + if (same_len && cfr < 0) { + /* Give priority to lower-case characters */ + cfr = (path1[j] > path2[j]); + } + continue; + } + cfr = (a < b); } break; } From f60228f61021096649d5d591dfbf3f801161ec75 Mon Sep 17 00:00:00 2001 From: vqn <85911372+vqns@users.noreply.github.com> Date: Mon, 10 Apr 2023 21:57:11 +0200 Subject: [PATCH 056/148] #1393 followup (#1463) * Fix incorrect check in doc:raw_remove Restore caret position on command doc:cut * merge cursors and fix new line in clipboard * add new line to the last copied line --- data/core/commands/doc.lua | 8 +++++--- data/core/doc/init.lua | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index eca876ea..d9803bce 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -62,10 +62,10 @@ local function cut_or_copy(delete) local text = "" core.cursor_clipboard = {} core.cursor_clipboard_whole_line = {} - for idx, line1, col1, line2, col2 in doc():get_selections() do + for idx, line1, col1, line2, col2 in doc():get_selections(true, true) do if line1 ~= line2 or col1 ~= col2 then text = doc():get_text(line1, col1, line2, col2) - full_text = full_text == "" and text or (full_text .. " " .. text) + full_text = full_text == "" and text or (text .. " " .. full_text) core.cursor_clipboard_whole_line[idx] = false if delete then doc():delete_to_cursor(idx, 0) @@ -73,7 +73,7 @@ local function cut_or_copy(delete) else -- Cut/copy whole line -- Remove newline from the text. It will be added as needed on paste. text = string.sub(doc().lines[line1], 1, -2) - full_text = full_text == "" and text or (full_text .. text .. "\n") + full_text = full_text == "" and text .. "\n" or (text .. "\n" .. full_text) core.cursor_clipboard_whole_line[idx] = true if delete then if line1 < #doc().lines then @@ -83,10 +83,12 @@ local function cut_or_copy(delete) else doc():remove(line1 - 1, math.huge, line1, math.huge) end + doc():set_selections(idx, line1, col1, line2, col2) end end core.cursor_clipboard[idx] = text end + if delete then doc():merge_cursors() end core.cursor_clipboard["full"] = full_text system.set_clipboard(full_text) end diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index 7fdd896c..74116fd5 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -453,7 +453,7 @@ function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time) end end - if cline2 > line1 or (cline2 == line2 and ccol2 > col1) then + if cline2 > line1 or (cline2 == line1 and ccol2 > col1) then if cline2 > line2 then l2 = l2 - line_removal else From 0d0f1b00d99d7a20c9ad40575e4fae2426224d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jefferson=20Gonz=C3=A1lez?= Date: Mon, 10 Apr 2023 21:29:31 -0400 Subject: [PATCH 057/148] Fix for api_require wrong macro && conditions (#1465) This mistake escaped my eyes when reviewing #1437 and causes some symbols to not be exported, because the preprocessor macros are expecting multiple LUA versions to evaluate as true at once. The fix is to replace `&&` with `||`. --- src/api/system.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/api/system.c b/src/api/system.c index 33e5c6c3..b8a27d39 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -916,7 +916,7 @@ typedef struct lua_function_node { #define S(FUNC) { #FUNC, (fptr)(FUNC) } static void* api_require(const char* symbol) { static const lua_function_node nodes[] = { - #if LUA_VERSION_NUM == 501 && LUA_VERSION_NUM == 502 && LUA_VERSION_NUM == 503 && LUA_VERSION_NUM == 504 + #if LUA_VERSION_NUM == 501 || LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 || LUA_VERSION_NUM == 504 U(addlstring), U(addstring), U(addvalue), U(argerror), U(buffinit), U(callmeta), U(checkany), U(checkinteger), U(checklstring), U(checknumber), U(checkoption), U(checkstack), U(checktype), @@ -939,7 +939,7 @@ static void* api_require(const char* symbol) { S(luaopen_math), S(luaopen_os), S(luaopen_package), S(luaopen_string), S(luaopen_table), S(api_load_libs), #endif - #if LUA_VERSION_NUM == 502 && LUA_VERSION_NUM == 503 && LUA_VERSION_NUM == 504 + #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 || LUA_VERSION_NUM == 504 U(buffinitsize), U(checkversion_), U(execresult), U(fileresult), U(getsubtable), U(len), U(loadbufferx), U(loadfilex), U(prepbuffsize), U(pushresultsize), U(requiref), U(setfuncs), U(setmetatable), @@ -949,17 +949,17 @@ static void* api_require(const char* symbol) { P(tonumberx), P(upvalueid), P(upvaluejoin), P(version), P(yieldk), S(luaopen_coroutine), #endif - #if LUA_VERSION_NUM == 501 && LUA_VERSION_NUM == 502 && LUA_VERSION_NUM == 503 + #if LUA_VERSION_NUM == 501 || LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 P(newuserdata), #endif - #if LUA_VERSION_NUM == 503 && LUA_VERSION_NUM == 504 + #if LUA_VERSION_NUM == 503 || LUA_VERSION_NUM == 504 P(geti), P(isinteger), P(isyieldable), P(rotate), P(seti), P(stringtonumber), S(luaopen_utf8), #endif - #if LUA_VERSION_NUM == 502 && LUA_VERSION_NUM == 503 + #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 P(getuservalue), P(setuservalue), S(luaopen_bit32), #endif - #if LUA_VERSION_NUM == 501 && LUA_VERSION_NUM == 502 + #if LUA_VERSION_NUM == 501 || LUA_VERSION_NUM == 502 P(insert), P(remove), P(replace), #endif #if LUA_VERSION_NUM == 504 From 1fe90da6643521f86e7f8bf1ded335562fc0e3bb Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:20:28 +0800 Subject: [PATCH 058/148] upgrade header files to Lua 5.4 (#1436) * refactor(native_api_header): upgrade header files to Lua 5.4. Almost all of the symbols in this file was from 5.2. This will obviously not work because some function signatures have changed and some have completely wrong return values, etc. This commit updates the header files to Lua 5.4 based on the source code and changes a few things. * refactor(plugin_api): move the header into include/ * fix(lite_xl_plugin_api.h): include stdlib to avoid errors with exit * refactor(lite_xl_plugin_api.h): do not return in SYMBOL_WRAP_CALL * fix(lite_xl_plugin_api.h): fix wrong way of passing varargs * fix(lite_xl_plugin_api.h): fix differing lua_rawlen definition * fix(lite_xl_plugin_api.h): fix fallback function signature * fix(lite_xl_plugin_api.h): fix conversion from void * to function pointer --- resources/include/lite_xl_plugin_api.h | 2563 ++++++++++++++++++++++++ resources/lite_xl_plugin_api.h | 1124 ----------- 2 files changed, 2563 insertions(+), 1124 deletions(-) create mode 100644 resources/include/lite_xl_plugin_api.h delete mode 100644 resources/lite_xl_plugin_api.h diff --git a/resources/include/lite_xl_plugin_api.h b/resources/include/lite_xl_plugin_api.h new file mode 100644 index 00000000..2947039e --- /dev/null +++ b/resources/include/lite_xl_plugin_api.h @@ -0,0 +1,2563 @@ +/** + * lite_xl_plugin_api.h + * API for writing C extension modules loaded by Lite XL. + * This file is licensed under MIT. + * + * The Lite XL plugin API is quite simple. + * You would write a lua C extension and replace any references to lua.h, lauxlib.h + * and lualib.h with lite_xl_plugin_api.h. + * In your main file (where your entrypoint resides), define LITE_XL_PLUGIN_ENTRYPOINT. + * If you have multiple entrypoints, define LITE_XL_PLUGIN_ENTRYPOINT in one of them. + * + * After that, you need to create a Lite XL entrypoint, which is formatted as + * luaopen_lite_xl_xxxxx instead of luaopen_xxxxx. + * This entrypoint accepts a lua_State and an extra parameter of type void *. + * In this entrypoint, call lite_xl_plugin_init() with the extra parameter. + * If you have multiple entrypoints, you must call lite_xl_plugin_init() in + * each of them. + * This function is not thread safe, so don't try to do anything stupid. + * + * An example: + * + * #define LITE_XL_PLUGIN_ENTRYPOINT + * #include "lite_xl_plugin_api.h" + * int luaopen_lite_xl_xxxxx(lua_State* L, void* XL) { + * lite_xl_plugin_init(XL); + * ... + * return 1; + * } + * + * You can compile the library just like any Lua library without linking to Lua. + * An example command would be: gcc -shared -o xxxxx.so xxxxx.c + * You must not link to ANY lua library to avoid symbol collision. + * + * This file contains stock configuration for a typical installation of Lua 5.4. + * DO NOT MODIFY ANYTHING. MODIFYING STUFFS IN HERE WILL BREAK + * COMPATIBILITY WITH LITE XL AND CAUSE UNDEBUGGABLE BUGS. +**/ +#ifndef LITE_XL_PLUGIN_API +#define LITE_XL_PLUGIN_API + +#include +#include + +#ifdef __GNUC__ +#define UNUSED __attribute__((__unused__)) +#else +#define UNUSED +#endif + +/* FOR_EACH macro */ +#define CONCAT(arg1, arg2) CONCAT1(arg1, arg2) +#define CONCAT1(arg1, arg2) CONCAT2(arg1, arg2) +#define CONCAT2(arg1, arg2) arg1##arg2 +#define FE_1(what, x) what x +#define FE_2(what, x, ...) what x,FE_1(what, __VA_ARGS__) +#define FE_3(what, x, ...) what x,FE_2(what, __VA_ARGS__) +#define FE_4(what, x, ...) what x,FE_3(what, __VA_ARGS__) +#define FE_5(what, x, ...) what x,FE_4(what, __VA_ARGS__) +#define FE_6(what, x, ...) what x,FE_5(what, __VA_ARGS__) +#define FE_7(what, x, ...) what x,FE_6(what, __VA_ARGS__) +#define FE_8(what, x, ...) what x,FE_7(what, __VA_ARGS__) +#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N()) +#define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__) +#define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N +#define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0 +#define FOR_EACH_(N, what, ...) CONCAT(FE_, N)(what, __VA_ARGS__) +#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__) + +#define SYMBOL_WRAP_DECL(ret, name, ...) \ + ret name(__VA_ARGS__) + +#define SYMBOL_WRAP_CALL(name, ...) \ + __##name(__VA_ARGS__) + +#define SYMBOL_WRAP_CALL_FB(name, ...) \ + return __lite_xl_fallback_##name(__VA_ARGS__) + +#ifdef LITE_XL_PLUGIN_ENTRYPOINT + #define SYMBOL_DECLARE(ret, name, ...) \ + static ret (*__##name) (__VA_ARGS__); \ + SYMBOL_WRAP_DECL(ret, name, __VA_ARGS__); \ + static ret __lite_xl_fallback_##name(FOR_EACH(UNUSED, __VA_ARGS__)) { \ + fputs("warning: " #name " is a stub", stderr); \ + exit(1); \ + } + #define SYMBOL_DECLARE_VARARG(ret, name, ...) \ + static ret (*__##name) (__VA_ARGS__, ...); \ + SYMBOL_WRAP_DECL(ret, name, __VA_ARGS__, ...); \ + static ret __lite_xl_fallback_##name(FOR_EACH(UNUSED, __VA_ARGS__), ...) { \ + fputs("warning: " #name " is a stub", stderr); \ + exit(1); \ + } +#else + #define SYMBOL_DECLARE(ret, name, ...) \ + SYMBOL_WRAP_DECL(ret, name, __VA_ARGS__); + #define SYMBOL_DECLARE_VARARG(ret, name, ...) \ + SYMBOL_WRAP_DECL(ret, name, __VA_ARGS__, ...); +#endif + + + + + +/* +** $Id: luaconf.h $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef luaconf_h +#define luaconf_h + +#include +#include + + +/* +** =================================================================== +** General Configuration File for Lua +** +** Some definitions here can be changed externally, through the compiler +** (e.g., with '-D' options): They are commented out or protected +** by '#if !defined' guards. However, several other definitions +** should be changed directly here, either because they affect the +** Lua ABI (by making the changes here, you ensure that all software +** connected to Lua, such as C libraries, will be compiled with the same +** configuration); or because they are seldom changed. +** +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +** {==================================================================== +** System Configuration: macros to adapt (if needed) Lua to some +** particular platform, for instance restricting it to C89. +** ===================================================================== +*/ + +/* +@@ LUA_USE_C89 controls the use of non-ISO-C89 features. +** Define it if you want Lua to avoid the use of a few C99 features +** or Windows-specific features on Windows. +*/ +/* #define LUA_USE_C89 */ + + +/* +** By default, Lua on Windows use (some) specific Windows features +*/ +#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE) +#define LUA_USE_WINDOWS /* enable goodies for regular Windows */ +#endif + + +#if defined(LUA_USE_WINDOWS) +#define LUA_DL_DLL /* enable support for DLL */ +#define LUA_USE_C89 /* broadly, Windows is C89 */ +#endif + + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#endif + + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ +#endif + + +/* +@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits. +*/ +#define LUAI_IS32INT ((UINT_MAX >> 30) >= 3) + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Number types. These options should not be +** set externally, because any other code connected to Lua must +** use the same configuration. +** =================================================================== +*/ + +/* +@@ LUA_INT_TYPE defines the type for Lua integers. +@@ LUA_FLOAT_TYPE defines the type for Lua floats. +** Lua should work fine with any mix of these options supported +** by your C compiler. The usual configurations are 64-bit integers +** and 'double' (the default), 32-bit integers and 'float' (for +** restricted platforms), and 'long'/'double' (for C compilers not +** compliant with C99, which may not have support for 'long long'). +*/ + +/* predefined options for LUA_INT_TYPE */ +#define LUA_INT_INT 1 +#define LUA_INT_LONG 2 +#define LUA_INT_LONGLONG 3 + +/* predefined options for LUA_FLOAT_TYPE */ +#define LUA_FLOAT_FLOAT 1 +#define LUA_FLOAT_DOUBLE 2 +#define LUA_FLOAT_LONGDOUBLE 3 + + +/* Default configuration ('long long' and 'double', for 64-bit Lua) */ +#define LUA_INT_DEFAULT LUA_INT_LONGLONG +#define LUA_FLOAT_DEFAULT LUA_FLOAT_DOUBLE + + +/* +@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. +*/ +#define LUA_32BITS 0 + + +/* +@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for +** C89 ('long' and 'double'); Windows always has '__int64', so it does +** not need to use this case. +*/ +#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) +#define LUA_C89_NUMBERS 1 +#else +#define LUA_C89_NUMBERS 0 +#endif + + +#if LUA_32BITS /* { */ +/* +** 32-bit integers and 'float' +*/ +#if LUAI_IS32INT /* use 'int' if big enough */ +#define LUA_INT_TYPE LUA_INT_INT +#else /* otherwise use 'long' */ +#define LUA_INT_TYPE LUA_INT_LONG +#endif +#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT + +#elif LUA_C89_NUMBERS /* }{ */ +/* +** largest types available for C89 ('long' and 'double') +*/ +#define LUA_INT_TYPE LUA_INT_LONG +#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE + +#else /* }{ */ +/* use defaults */ + +#define LUA_INT_TYPE LUA_INT_DEFAULT +#define LUA_FLOAT_TYPE LUA_FLOAT_DEFAULT + +#endif /* } */ + + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Paths. +** =================================================================== +*/ + +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +*/ +#define LUA_PATH_SEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXEC_DIR "!" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +** Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +** C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ + +#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#if defined(_WIN32) /* { */ +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" + +#if !defined(LUA_PATH_DEFAULT) +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ + LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ + ".\\?.lua;" ".\\?\\init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.dll;" \ + LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ + LUA_CDIR"loadall.dll;" ".\\?.dll" +#endif + +#else /* }{ */ + +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" +#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" + +#if !defined(LUA_PATH_DEFAULT) +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ + "./?.lua;" "./?/init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" +#endif + +#endif /* } */ + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if !defined(LUA_DIRSEP) + +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + +#endif + +/* }================================================================== */ + + +/* +** {================================================================== +** Marks for exported symbols in the C code +** =================================================================== +*/ + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all auxiliary library functions. +@@ LUAMOD_API is a mark for all standard library opening functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) /* { */ + +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ +#define LUA_API __declspec(dllexport) +#else /* }{ */ +#define LUA_API __declspec(dllimport) +#endif /* } */ + +#else /* }{ */ + +#define LUA_API extern + +#endif /* } */ + + +/* +** More often than not the libs go together with the core. +*/ +#define LUALIB_API LUA_API +#define LUAMOD_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +** exported to outside modules. +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables, +** none of which to be exported to outside modules (LUAI_DDEF for +** definitions and LUAI_DDEC for declarations). +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. Not all elf targets support +** this attribute. Unfortunately, gcc does not offer a way to check +** whether the target offers that support, and those without support +** give a warning about it. To avoid these warnings, change to the +** default definition. +*/ +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ +#define LUAI_FUNC __attribute__((visibility("internal"))) extern +#else /* }{ */ +#define LUAI_FUNC extern +#endif /* } */ + +#define LUAI_DDEC(dec) LUAI_FUNC dec +#define LUAI_DDEF /* empty */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Compatibility with previous versions +** =================================================================== +*/ + +/* +@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3. +** You can define it to get all options, or change specific options +** to fit your specific needs. +*/ +#if defined(LUA_COMPAT_5_3) /* { */ + +/* +@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated +** functions in the mathematical library. +** (These functions were already officially removed in 5.3; +** nevertheless they are still available here.) +*/ +#define LUA_COMPAT_MATHLIB + +/* +@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for +** manipulating other integer types (lua_pushunsigned, lua_tounsigned, +** luaL_checkint, luaL_checklong, etc.) +** (These macros were also officially removed in 5.3, but they are still +** available here.) +*/ +#define LUA_COMPAT_APIINTCASTS + + +/* +@@ LUA_COMPAT_LT_LE controls the emulation of the '__le' metamethod +** using '__lt'. +*/ +#define LUA_COMPAT_LT_LE + + +/* +@@ The following macros supply trivial compatibility for some +** changes in the API. The macros themselves document how to +** change your code to avoid using them. +** (Once more, these macros were officially removed in 5.3, but they are +** still available here.) +*/ +#define lua_strlen(L,i) lua_rawlen(L, (i)) + +#define lua_objlen(L,i) lua_rawlen(L, (i)) + +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) + +#endif /* } */ + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Numbers (low-level part). +** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_* +** satisfy your needs. +** =================================================================== +*/ + +/* +@@ LUAI_UACNUMBER is the result of a 'default argument promotion' +@@ over a floating number. +@@ l_floatatt(x) corrects float attribute 'x' to the proper float type +** by prefixing it with one of FLT/DBL/LDBL. +@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. +@@ LUA_NUMBER_FMT is the format for writing floats. +@@ lua_number2str converts a float to a string. +@@ l_mathop allows the addition of an 'l' or 'f' to all math operations. +@@ l_floor takes the floor of a float. +@@ lua_str2number converts a decimal numeral to a number. +*/ + + +/* The following definitions are good for most cases here */ + +#define l_floor(x) (l_mathop(floor)(x)) + +#define lua_number2str(s,sz,n) \ + l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n)) + +/* +@@ lua_numbertointeger converts a float number with an integral value +** to an integer, or returns 0 if float is not within the range of +** a lua_Integer. (The range comparisons are tricky because of +** rounding. The tests here assume a two-complement representation, +** where MININTEGER always has an exact representation as a float; +** MAXINTEGER may not have one, and therefore its conversion to float +** may have an ill-defined value.) +*/ +#define lua_numbertointeger(n,p) \ + ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ + (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ + (*(p) = (LUA_INTEGER)(n), 1)) + + +/* now the variable definitions */ + +#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */ + +#define LUA_NUMBER float + +#define l_floatatt(n) (FLT_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.7g" + +#define l_mathop(op) op##f + +#define lua_str2number(s,p) strtof((s), (p)) + + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */ + +#define LUA_NUMBER long double + +#define l_floatatt(n) (LDBL_##n) + +#define LUAI_UACNUMBER long double + +#define LUA_NUMBER_FRMLEN "L" +#define LUA_NUMBER_FMT "%.19Lg" + +#define l_mathop(op) op##l + +#define lua_str2number(s,p) strtold((s), (p)) + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */ + +#define LUA_NUMBER double + +#define l_floatatt(n) (DBL_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.14g" + +#define l_mathop(op) op + +#define lua_str2number(s,p) strtod((s), (p)) + +#else /* }{ */ + +#error "numeric float type not defined" + +#endif /* } */ + + + +/* +@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. +@@ LUAI_UACINT is the result of a 'default argument promotion' +@@ over a LUA_INTEGER. +@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. +@@ LUA_INTEGER_FMT is the format for writing integers. +@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. +@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. +@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED. +@@ lua_integer2str converts an integer to a string. +*/ + + +/* The following definitions are good for most cases here */ + +#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" + +#define LUAI_UACINT LUA_INTEGER + +#define lua_integer2str(s,sz,n) \ + l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n)) + +/* +** use LUAI_UACINT here to avoid problems with promotions (which +** can turn a comparison between unsigneds into a signed comparison) +*/ +#define LUA_UNSIGNED unsigned LUAI_UACINT + + +/* now the variable definitions */ + +#if LUA_INT_TYPE == LUA_INT_INT /* { int */ + +#define LUA_INTEGER int +#define LUA_INTEGER_FRMLEN "" + +#define LUA_MAXINTEGER INT_MAX +#define LUA_MININTEGER INT_MIN + +#define LUA_MAXUNSIGNED UINT_MAX + +#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */ + +#define LUA_INTEGER long +#define LUA_INTEGER_FRMLEN "l" + +#define LUA_MAXINTEGER LONG_MAX +#define LUA_MININTEGER LONG_MIN + +#define LUA_MAXUNSIGNED ULONG_MAX + +#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ + +/* use presence of macro LLONG_MAX as proxy for C99 compliance */ +#if defined(LLONG_MAX) /* { */ +/* use ISO C99 stuff */ + +#define LUA_INTEGER long long +#define LUA_INTEGER_FRMLEN "ll" + +#define LUA_MAXINTEGER LLONG_MAX +#define LUA_MININTEGER LLONG_MIN + +#define LUA_MAXUNSIGNED ULLONG_MAX + +#elif defined(LUA_USE_WINDOWS) /* }{ */ +/* in Windows, can use specific Windows types */ + +#define LUA_INTEGER __int64 +#define LUA_INTEGER_FRMLEN "I64" + +#define LUA_MAXINTEGER _I64_MAX +#define LUA_MININTEGER _I64_MIN + +#define LUA_MAXUNSIGNED _UI64_MAX + +#else /* }{ */ + +#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ + or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)" + +#endif /* } */ + +#else /* }{ */ + +#error "numeric integer type not defined" + +#endif /* } */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Dependencies with C99 and other C details +** =================================================================== +*/ + +/* +@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89. +** (All uses in Lua have only one format item.) +*/ +#if !defined(LUA_USE_C89) +#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i) +#else +#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i)) +#endif + + +/* +@@ lua_strx2number converts a hexadecimal numeral to a number. +** In C99, 'strtod' does that conversion. Otherwise, you can +** leave 'lua_strx2number' undefined and Lua will provide its own +** implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_strx2number(s,p) lua_str2number(s,p) +#endif + + +/* +@@ lua_pointer2str converts a pointer to a readable string in a +** non-specified way. +*/ +#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p) + + +/* +@@ lua_number2strx converts a float to a hexadecimal numeral. +** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. +** Otherwise, you can leave 'lua_number2strx' undefined and Lua will +** provide its own implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_number2strx(L,b,sz,f,n) \ + ((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n))) +#endif + + +/* +** 'strtof' and 'opf' variants for math functions are not valid in +** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the +** availability of these variants. ('math.h' is already included in +** all files that use these macros.) +*/ +#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF)) +#undef l_mathop /* variants not available */ +#undef lua_str2number +#define l_mathop(op) (lua_Number)op /* no variant */ +#define lua_str2number(s,p) ((lua_Number)strtod((s), (p))) +#endif + + +/* +@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation +** functions. It must be a numerical type; Lua will use 'intptr_t' if +** available, otherwise it will use 'ptrdiff_t' (the nearest thing to +** 'intptr_t' in C89) +*/ +#define LUA_KCONTEXT ptrdiff_t + +#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 199901L +#include +#if defined(INTPTR_MAX) /* even in C99 this type is optional */ +#undef LUA_KCONTEXT +#define LUA_KCONTEXT intptr_t +#endif +#endif + + +/* +@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point). +** Change that if you do not want to use C locales. (Code using this +** macro must include the header 'locale.h'.) +*/ +#if !defined(lua_getlocaledecpoint) +#define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) +#endif + + +/* +** macros to improve jump prediction, used mostly for error handling +** and debug facilities. (Some macros in the Lua API use these macros. +** Define LUA_NOBUILTIN if you do not want '__builtin_expect' in your +** code.) +*/ +#if !defined(luai_likely) + +#if defined(__GNUC__) && !defined(LUA_NOBUILTIN) +#define luai_likely(x) (__builtin_expect(((x) != 0), 1)) +#define luai_unlikely(x) (__builtin_expect(((x) != 0), 0)) +#else +#define luai_likely(x) (x) +#define luai_unlikely(x) (x) +#endif + +#endif + + +#if defined(LUA_CORE) || defined(LUA_LIB) +/* shorter names for Lua's own use */ +#define l_likely(x) luai_likely(x) +#define l_unlikely(x) luai_unlikely(x) +#endif + + + +/* }================================================================== */ + + +/* +** {================================================================== +** Language Variations +** ===================================================================== +*/ + +/* +@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some +** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from +** numbers to strings. Define LUA_NOCVTS2N to turn off automatic +** coercion from strings to numbers. +*/ +/* #define LUA_NOCVTN2S */ +/* #define LUA_NOCVTS2N */ + + +/* +@@ LUA_USE_APICHECK turns on several consistency checks on the C API. +** Define it as a help when debugging C code. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(l,e) assert(e) +#endif + +/* }================================================================== */ + + +/* +** {================================================================== +** Macros that affect the API and must be stable (that is, must be the +** same when you compile Lua and when you compile code that links to +** Lua). +** ===================================================================== +*/ + +/* +@@ LUAI_MAXSTACK limits the size of the Lua stack. +** CHANGE it if you need a different limit. This limit is arbitrary; +** its only purpose is to stop Lua from consuming unlimited stack +** space (and to reserve some numbers for pseudo-indices). +** (It must fit into max(size_t)/32.) +*/ +#if LUAI_IS32INT +#define LUAI_MAXSTACK 1000000 +#else +#define LUAI_MAXSTACK 15000 +#endif + + +/* +@@ LUA_EXTRASPACE defines the size of a raw memory area associated with +** a Lua state with very fast access. +** CHANGE it if you need a different size. +*/ +#define LUA_EXTRASPACE (sizeof(void *)) + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@@ of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number))) + + +/* +@@ LUAI_MAXALIGN defines fields that, when used in a union, ensure +** maximum alignment for the other items in that union. +*/ +#define LUAI_MAXALIGN lua_Number n; double u; void *s; lua_Integer i; long l + +/* }================================================================== */ + +#endif + + + + + +/* +** $Id: lua.h $ +** Lua - A Scripting Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#define LUA_VERSION_MAJOR "5" +#define LUA_VERSION_MINOR "4" +#define LUA_VERSION_RELEASE "4" + +#define LUA_VERSION_NUM 504 +#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 4) + +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2022 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" + + +/* mark for precompiled code ('Lua') */ +#define LUA_SIGNATURE "\x1bLua" + +/* option for multiple returns in 'lua_pcall' and 'lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** Pseudo-indices +** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty +** space after that to help overflow detection) +*/ +#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000) +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) + + +/* thread status */ +#define LUA_OK 0 +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + +#define LUA_NUMTYPES 9 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* predefined values in the registry */ +#define LUA_RIDX_MAINTHREAD 1 +#define LUA_RIDX_GLOBALS 2 +#define LUA_RIDX_LAST LUA_RIDX_GLOBALS + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + +/* unsigned integer type */ +typedef LUA_UNSIGNED lua_Unsigned; + +/* type for continuation-function contexts */ +typedef LUA_KCONTEXT lua_KContext; + + +/* +** Type for C functions registered with Lua +*/ +typedef int (*lua_CFunction) (lua_State *L); + +/* +** Type for continuation functions +*/ +typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); + + +/* +** Type for functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud); + + +/* +** Type for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** Type for warning functions +*/ +typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); + + + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* +** RCS ident string +*/ +extern const char lua_ident[]; + + +/* +** state manipulation +*/ +SYMBOL_DECLARE(lua_State *, lua_newstate, lua_Alloc f, void *ud) +SYMBOL_DECLARE(void, lua_close, lua_State *L) +SYMBOL_DECLARE(lua_State *, lua_newthread, lua_State *L) +SYMBOL_DECLARE(int, lua_resetthread, lua_State *L) + +SYMBOL_DECLARE(lua_CFunction, lua_atpanic, lua_State *L, lua_CFunction panicf) + + +SYMBOL_DECLARE(lua_Number, lua_version, lua_State *L) + + +/* +** basic stack manipulation +*/ +SYMBOL_DECLARE(int , lua_absindex, lua_State *L, int idx) +SYMBOL_DECLARE(int , lua_gettop, lua_State *L) +SYMBOL_DECLARE(void, lua_settop, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_pushvalue, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_rotate, lua_State *L, int idx, int n) +SYMBOL_DECLARE(void, lua_copy, lua_State *L, int fromidx, int toidx) +SYMBOL_DECLARE(int , lua_checkstack, lua_State *L, int n) + +SYMBOL_DECLARE(void, lua_xmove, lua_State *from, lua_State *to, int n) + + +/* +** access functions (stack -> C) +*/ + +SYMBOL_DECLARE(int , lua_isnumber, lua_State *L, int idx) +SYMBOL_DECLARE(int , lua_isstring, lua_State *L, int idx) +SYMBOL_DECLARE(int , lua_iscfunction, lua_State *L, int idx) +SYMBOL_DECLARE(int , lua_isinteger, lua_State *L, int idx) +SYMBOL_DECLARE(int , lua_isuserdata, lua_State *L, int idx) +SYMBOL_DECLARE(int , lua_type, lua_State *L, int idx) +SYMBOL_DECLARE(const char *, lua_typename, lua_State *L, int tp) + +SYMBOL_DECLARE(lua_Number , lua_tonumberx, lua_State *L, int idx, int *isnum) +SYMBOL_DECLARE(lua_Integer , lua_tointegerx, lua_State *L, int idx, int *isnum) +SYMBOL_DECLARE(int , lua_toboolean, lua_State *L, int idx) +SYMBOL_DECLARE(const char *, lua_tolstring, lua_State *L, int idx, size_t *len) +SYMBOL_DECLARE(lua_Unsigned , lua_rawlen, lua_State *L, int idx) +SYMBOL_DECLARE(lua_CFunction , lua_tocfunction, lua_State *L, int idx) +SYMBOL_DECLARE(void *, lua_touserdata, lua_State *L, int idx) +SYMBOL_DECLARE(lua_State *, lua_tothread, lua_State *L, int idx) +SYMBOL_DECLARE(const void *, lua_topointer, lua_State *L, int idx) + + +/* +** Comparison and arithmetic functions +*/ + +#define LUA_OPADD 0 /* ORDER TM, ORDER OP */ +#define LUA_OPSUB 1 +#define LUA_OPMUL 2 +#define LUA_OPMOD 3 +#define LUA_OPPOW 4 +#define LUA_OPDIV 5 +#define LUA_OPIDIV 6 +#define LUA_OPBAND 7 +#define LUA_OPBOR 8 +#define LUA_OPBXOR 9 +#define LUA_OPSHL 10 +#define LUA_OPSHR 11 +#define LUA_OPUNM 12 +#define LUA_OPBNOT 13 + +SYMBOL_DECLARE(void , lua_arith, lua_State *L, int op) + +#define LUA_OPEQ 0 +#define LUA_OPLT 1 +#define LUA_OPLE 2 + +SYMBOL_DECLARE(int , lua_rawequal, lua_State *L, int idx1, int idx2) +SYMBOL_DECLARE(int , lua_compare, lua_State *L, int idx1, int idx2, int op) + + +/* +** push functions (C -> stack) +*/ +SYMBOL_DECLARE(void , lua_pushnil, lua_State *L) +SYMBOL_DECLARE(void , lua_pushnumber, lua_State *L, lua_Number n) +SYMBOL_DECLARE(void , lua_pushinteger, lua_State *L, lua_Integer n) +SYMBOL_DECLARE(const char *, lua_pushlstring, lua_State *L, const char *s, size_t len) +SYMBOL_DECLARE(const char *, lua_pushstring, lua_State *L, const char *s) +SYMBOL_DECLARE(const char *, lua_pushvfstring, lua_State *L, const char *fmt, + va_list argp) +SYMBOL_DECLARE_VARARG(const char *, lua_pushfstring, lua_State *L, const char *fmt) +SYMBOL_DECLARE(void , lua_pushcclosure, lua_State *L, lua_CFunction fn, int n) +SYMBOL_DECLARE(void , lua_pushboolean, lua_State *L, int b) +SYMBOL_DECLARE(void , lua_pushlightuserdata, lua_State *L, void *p) +SYMBOL_DECLARE(int , lua_pushthread, lua_State *L) + + +/* +** get functions (Lua -> stack) +*/ +SYMBOL_DECLARE(int , lua_getglobal, lua_State *L, const char *name) +SYMBOL_DECLARE(int , lua_gettable, lua_State *L, int idx) +SYMBOL_DECLARE(int , lua_getfield, lua_State *L, int idx, const char *k) +SYMBOL_DECLARE(int , lua_geti, lua_State *L, int idx, lua_Integer n) +SYMBOL_DECLARE(int , lua_rawget, lua_State *L, int idx) +SYMBOL_DECLARE(int , lua_rawgeti, lua_State *L, int idx, lua_Integer n) +SYMBOL_DECLARE(int , lua_rawgetp, lua_State *L, int idx, const void *p) + +SYMBOL_DECLARE(void , lua_createtable, lua_State *L, int narr, int nrec) +SYMBOL_DECLARE(void *, lua_newuserdatauv, lua_State *L, size_t sz, int nuvalue) +SYMBOL_DECLARE(int , lua_getmetatable, lua_State *L, int objindex) +SYMBOL_DECLARE(int , lua_getiuservalue, lua_State *L, int idx, int n) + + +/* +** set functions (stack -> Lua) +*/ +SYMBOL_DECLARE(void , lua_setglobal, lua_State *L, const char *name) +SYMBOL_DECLARE(void , lua_settable, lua_State *L, int idx) +SYMBOL_DECLARE(void , lua_setfield, lua_State *L, int idx, const char *k) +SYMBOL_DECLARE(void , lua_seti, lua_State *L, int idx, lua_Integer n) +SYMBOL_DECLARE(void , lua_rawset, lua_State *L, int idx) +SYMBOL_DECLARE(void , lua_rawseti, lua_State *L, int idx, lua_Integer n) +SYMBOL_DECLARE(void , lua_rawsetp, lua_State *L, int idx, const void *p) +SYMBOL_DECLARE(int , lua_setmetatable, lua_State *L, int objindex) +SYMBOL_DECLARE(int , lua_setiuservalue, lua_State *L, int idx, int n) + + +/* +** 'load' and 'call' functions (load and run Lua code) +*/ +SYMBOL_DECLARE(void, lua_callk, lua_State *L, int nargs, int nresults, + lua_KContext ctx, lua_KFunction k) +#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) + +SYMBOL_DECLARE(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, + lua_KContext ctx, lua_KFunction k) +#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) + +SYMBOL_DECLARE(int, lua_load, lua_State *L, lua_Reader reader, void *dt, + const char *chunkname, const char *mode) + +SYMBOL_DECLARE(int, lua_dump, lua_State *L, lua_Writer writer, void *data, int strip) + + +/* +** coroutine functions +*/ +SYMBOL_DECLARE(int, lua_yieldk, lua_State *L, int nresults, lua_KContext ctx, + lua_KFunction k) +SYMBOL_DECLARE(int, lua_resume, lua_State *L, lua_State *from, int narg, + int *nres) +SYMBOL_DECLARE(int, lua_status, lua_State *L) +SYMBOL_DECLARE(int, lua_isyieldable, lua_State *L) + +#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) + + +/* +** Warning-related functions +*/ +SYMBOL_DECLARE(void, lua_setwarnf, lua_State *L, lua_WarnFunction f, void *ud) +SYMBOL_DECLARE(void, lua_warning, lua_State *L, const char *msg, int tocont) + + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 +#define LUA_GCISRUNNING 9 +#define LUA_GCGEN 10 +#define LUA_GCINC 11 + +SYMBOL_DECLARE_VARARG(int, lua_gc, lua_State *L, int what) + + +/* +** miscellaneous functions +*/ + +SYMBOL_DECLARE(int , lua_error, lua_State *L) + +SYMBOL_DECLARE(int , lua_next, lua_State *L, int idx) + +SYMBOL_DECLARE(void, lua_concat, lua_State *L, int n) +SYMBOL_DECLARE(void, lua_len, lua_State *L, int idx) + +SYMBOL_DECLARE(size_t, lua_stringtonumber, lua_State *L, const char *s) + +SYMBOL_DECLARE(lua_Alloc, lua_getallocf, lua_State *L, void **ud) +SYMBOL_DECLARE(void , lua_setallocf, lua_State *L, lua_Alloc f, void *ud) + +SYMBOL_DECLARE(void, lua_toclose, lua_State *L, int idx) +SYMBOL_DECLARE(void, lua_closeslot, lua_State *L, int idx) + + +/* +** {============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE)) + +#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL) +#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL) + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) lua_pushstring(L, "" s) + +#define lua_pushglobaltable(L) \ + ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + +#define lua_insert(L,idx) lua_rotate(L, (idx), 1) + +#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) + +#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1)) + +/* }============================================================== */ + + +/* +** {============================================================== +** compatibility macros +** =============================================================== +*/ +#if defined(LUA_COMPAT_APIINTCASTS) + +#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) +#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is)) +#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) + +#endif + +#define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1) +#define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1) +#define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1) + +#define LUA_NUMTAGS LUA_NUMTYPES + +/* }============================================================== */ + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILCALL 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debugger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +SYMBOL_DECLARE(int, lua_getstack, lua_State *L, int level, lua_Debug *ar) +SYMBOL_DECLARE(int, lua_getinfo, lua_State *L, const char *what, lua_Debug *ar) +SYMBOL_DECLARE(const char *, lua_getlocal, lua_State *L, const lua_Debug *ar, int n) +SYMBOL_DECLARE(const char *, lua_setlocal, lua_State *L, const lua_Debug *ar, int n) +SYMBOL_DECLARE(const char *, lua_getupvalue, lua_State *L, int funcindex, int n) +SYMBOL_DECLARE(const char *, lua_setupvalue, lua_State *L, int funcindex, int n) + +SYMBOL_DECLARE(void *, lua_upvalueid, lua_State *L, int fidx, int n) +SYMBOL_DECLARE(void, lua_upvaluejoin, lua_State *L, int fidx1, int n1, + int fidx2, int n2) + +SYMBOL_DECLARE(void, lua_sethook, lua_State *L, lua_Hook func, int mask, int count) +SYMBOL_DECLARE(lua_Hook, lua_gethook, lua_State *L) +SYMBOL_DECLARE(int, lua_gethookmask, lua_State *L) +SYMBOL_DECLARE(int, lua_gethookcount, lua_State *L) + +SYMBOL_DECLARE(int, lua_setcstacklimit, lua_State *L, unsigned int limit) + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ + const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ + const char *source; /* (S) */ + size_t srclen; /* (S) */ + int currentline; /* (l) */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + unsigned char nups; /* (u) number of upvalues */ + unsigned char nparams;/* (u) number of parameters */ + char isvararg; /* (u) */ + char istailcall; /* (t) */ + unsigned short ftransfer; /* (r) index of first value transferred */ + unsigned short ntransfer; /* (r) number of transferred values */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + struct CallInfo *i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +#endif + + + + + +/* +** $Id: lauxlib.h $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + + +/* global table */ +#define LUA_GNAME "_G" + + +typedef struct luaL_Buffer luaL_Buffer; + + +/* extra error code for 'luaL_loadfilex' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +/* key, in the registry, for table of loaded modules */ +#define LUA_LOADED_TABLE "_LOADED" + + +/* key, in the registry, for table of preloaded loaders */ +#define LUA_PRELOAD_TABLE "_PRELOAD" + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + +#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) + +SYMBOL_DECLARE(void, luaL_checkversion_, lua_State *L, lua_Number ver, size_t sz) +#define luaL_checkversion(L) \ + luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) + +SYMBOL_DECLARE(int, luaL_getmetafield, lua_State *L, int obj, const char *e) +SYMBOL_DECLARE(int, luaL_callmeta, lua_State *L, int obj, const char *e) +SYMBOL_DECLARE(const char *, luaL_tolstring, lua_State *L, int idx, size_t *len) +SYMBOL_DECLARE(int, luaL_argerror, lua_State *L, int arg, const char *extramsg) +SYMBOL_DECLARE(int, luaL_typeerror, lua_State *L, int arg, const char *tname) +SYMBOL_DECLARE(const char *, luaL_checklstring, lua_State *L, int arg, + size_t *l) +SYMBOL_DECLARE(const char *, luaL_optlstring, lua_State *L, int arg, + const char *def, size_t *l) +SYMBOL_DECLARE(lua_Number, luaL_checknumber, lua_State *L, int arg) +SYMBOL_DECLARE(lua_Number, luaL_optnumber, lua_State *L, int arg, lua_Number def) + +SYMBOL_DECLARE(lua_Integer, luaL_checkinteger, lua_State *L, int arg) +SYMBOL_DECLARE(lua_Integer, luaL_optinteger, lua_State *L, int arg, + lua_Integer def) + +SYMBOL_DECLARE(void, luaL_checkstack, lua_State *L, int sz, const char *msg) +SYMBOL_DECLARE(void, luaL_checktype, lua_State *L, int arg, int t) +SYMBOL_DECLARE(void, luaL_checkany, lua_State *L, int arg) + +SYMBOL_DECLARE(int , luaL_newmetatable, lua_State *L, const char *tname) +SYMBOL_DECLARE(void , luaL_setmetatable, lua_State *L, const char *tname) +SYMBOL_DECLARE(void *, luaL_testudata, lua_State *L, int ud, const char *tname) +SYMBOL_DECLARE(void *, luaL_checkudata, lua_State *L, int ud, const char *tname) + +SYMBOL_DECLARE(void, luaL_where, lua_State *L, int lvl) +SYMBOL_DECLARE_VARARG(int, luaL_error, lua_State *L, const char *fmt) + +SYMBOL_DECLARE(int, luaL_checkoption, lua_State *L, int arg, const char *def, + const char *const lst[]) + +SYMBOL_DECLARE(int, luaL_fileresult, lua_State *L, int stat, const char *fname) +SYMBOL_DECLARE(int, luaL_execresult, lua_State *L, int stat) + + +/* predefined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +SYMBOL_DECLARE(int, luaL_ref, lua_State *L, int t) +SYMBOL_DECLARE(void, luaL_unref, lua_State *L, int t, int ref) + +SYMBOL_DECLARE(int, luaL_loadfilex, lua_State *L, const char *filename, + const char *mode) + +#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) + +SYMBOL_DECLARE(int, luaL_loadbufferx, lua_State *L, const char *buff, size_t sz, + const char *name, const char *mode) +SYMBOL_DECLARE(int, luaL_loadstring, lua_State *L, const char *s) + +SYMBOL_DECLARE(lua_State *, luaL_newstate, void) + +SYMBOL_DECLARE(lua_Integer, luaL_len, lua_State *L, int idx) + +SYMBOL_DECLARE(void, luaL_addgsub, luaL_Buffer *b, const char *s, + const char *p, const char *r) +SYMBOL_DECLARE(const char *, luaL_gsub, lua_State *L, const char *s, + const char *p, const char *r) + +SYMBOL_DECLARE(void, luaL_setfuncs, lua_State *L, const luaL_Reg *l, int nup) + +SYMBOL_DECLARE(int, luaL_getsubtable, lua_State *L, int idx, const char *fname) + +SYMBOL_DECLARE(void, luaL_traceback, lua_State *L, lua_State *L1, + const char *msg, int level) + +SYMBOL_DECLARE(void, luaL_requiref, lua_State *L, const char *modname, + lua_CFunction openf, int glb) + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + + +#define luaL_newlibtable(L,l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) + +#define luaL_newlib(L,l) \ + (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) + +#define luaL_argcheck(L, cond,arg,extramsg) \ + ((void)(luai_likely(cond) || luaL_argerror(L, (arg), (extramsg)))) + +#define luaL_argexpected(L,cond,arg,tname) \ + ((void)(luai_likely(cond) || luaL_typeerror(L, (arg), (tname)))) + +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) + + +/* +** Perform arithmetic operations on lua_Integer values with wrap-around +** semantics, as the Lua core does. +*/ +#define luaL_intop(op,v1,v2) \ + ((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2))) + + +/* push the value used to represent failure/error */ +#define luaL_pushfail(L) lua_pushnil(L) + + +/* +** Internal assertions for in-house debugging +*/ +#if !defined(lua_assert) + +#if defined LUAI_ASSERT + #include + #define lua_assert(c) assert(c) +#else + #define lua_assert(c) ((void)0) +#endif + +#endif + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +struct luaL_Buffer { + char *b; /* buffer address */ + size_t size; /* buffer size */ + size_t n; /* number of characters in buffer */ + lua_State *L; + union { + LUAI_MAXALIGN; /* ensure maximum alignment for buffer */ + char b[LUAL_BUFFERSIZE]; /* initial buffer */ + } init; +}; + + +#define luaL_bufflen(bf) ((bf)->n) +#define luaL_buffaddr(bf) ((bf)->b) + + +#define luaL_addchar(B,c) \ + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ + ((B)->b[(B)->n++] = (c))) + +#define luaL_addsize(B,s) ((B)->n += (s)) + +#define luaL_buffsub(B,s) ((B)->n -= (s)) + +SYMBOL_DECLARE(void, luaL_buffinit, lua_State *L, luaL_Buffer *B) +SYMBOL_DECLARE(char *, luaL_prepbuffsize, luaL_Buffer *B, size_t sz) +SYMBOL_DECLARE(void, luaL_addlstring, luaL_Buffer *B, const char *s, size_t l) +SYMBOL_DECLARE(void, luaL_addstring, luaL_Buffer *B, const char *s) +SYMBOL_DECLARE(void, luaL_addvalue, luaL_Buffer *B) +SYMBOL_DECLARE(void, luaL_pushresult, luaL_Buffer *B) +SYMBOL_DECLARE(void, luaL_pushresultsize, luaL_Buffer *B, size_t sz) +SYMBOL_DECLARE(char *, luaL_buffinitsize, lua_State *L, luaL_Buffer *B, size_t sz) + +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) + +/* }====================================================== */ + + + +/* +** {====================================================== +** File handles for IO library +** ======================================================= +*/ + +/* +** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and +** initial structure 'luaL_Stream' (it may contain other fields +** after that initial structure). +*/ + +#define LUA_FILEHANDLE "FILE*" + + +typedef struct luaL_Stream { + FILE *f; /* stream (NULL for incompletely created streams) */ + lua_CFunction closef; /* to close stream (NULL for closed streams) */ +} luaL_Stream; + +/* }====================================================== */ + +/* +** {================================================================== +** "Abstraction Layer" for basic report of messages and errors +** =================================================================== +*/ + +/* print a string */ +#if !defined(lua_writestring) +#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) +#endif + +/* print a newline and flush the output */ +#if !defined(lua_writeline) +#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) +#endif + +/* print an error message */ +#if !defined(lua_writestringerror) +#define lua_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) +#endif + +/* }================================================================== */ + + +/* +** {============================================================ +** Compatibility with deprecated conversions +** ============================================================= +*/ +#if defined(LUA_COMPAT_APIINTCASTS) + +#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) +#define luaL_optunsigned(L,a,d) \ + ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) + +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) + +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#endif +/* }============================================================ */ + + + +#endif + + + + + +/* +** $Id: lualib.h $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + + +/* version suffix for environment variable names */ +#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + + +SYMBOL_DECLARE(int, luaopen_base, lua_State *L) + +#define LUA_COLIBNAME "coroutine" +SYMBOL_DECLARE(int, luaopen_coroutine, lua_State *L) + +#define LUA_TABLIBNAME "table" +SYMBOL_DECLARE(int, luaopen_table, lua_State *L) + +#define LUA_IOLIBNAME "io" +SYMBOL_DECLARE(int, luaopen_io, lua_State *L) + +#define LUA_OSLIBNAME "os" +SYMBOL_DECLARE(int, luaopen_os, lua_State *L) + +#define LUA_STRLIBNAME "string" +SYMBOL_DECLARE(int, luaopen_string, lua_State *L) + +#define LUA_UTF8LIBNAME "utf8" +SYMBOL_DECLARE(int, luaopen_utf8, lua_State *L) + +#define LUA_MATHLIBNAME "math" +SYMBOL_DECLARE(int, luaopen_math, lua_State *L) + +#define LUA_DBLIBNAME "debug" +SYMBOL_DECLARE(int, luaopen_debug, lua_State *L) + +#define LUA_LOADLIBNAME "package" +SYMBOL_DECLARE(int, luaopen_package, lua_State *L) + + +/* open all previous libraries */ +SYMBOL_DECLARE(void, luaL_openlibs, lua_State *L) + + +#endif + + + + + +#ifdef LITE_XL_PLUGIN_ENTRYPOINT + +SYMBOL_WRAP_DECL(lua_State *, lua_newstate, lua_Alloc f, void *ud) { + return SYMBOL_WRAP_CALL(lua_newstate, f, ud); +} +SYMBOL_WRAP_DECL(void, lua_close, lua_State *L) { + SYMBOL_WRAP_CALL(lua_close, L); +} +SYMBOL_WRAP_DECL(lua_State *, lua_newthread, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_newthread, L); +} +SYMBOL_WRAP_DECL(int, lua_resetthread, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_resetthread, L); +} + +SYMBOL_WRAP_DECL(lua_CFunction, lua_atpanic, lua_State *L, lua_CFunction panicf) { + return SYMBOL_WRAP_CALL(lua_atpanic, L, panicf); +} + + +SYMBOL_WRAP_DECL(lua_Number, lua_version, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_version, L); +} + + + + + +SYMBOL_WRAP_DECL(int, lua_absindex, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_absindex, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_gettop, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_gettop, L); +} +SYMBOL_WRAP_DECL(void, lua_settop, lua_State *L, int idx) { + SYMBOL_WRAP_CALL(lua_settop, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_pushvalue, lua_State *L, int idx) { + SYMBOL_WRAP_CALL(lua_pushvalue, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_rotate, lua_State *L, int idx, int n) { + SYMBOL_WRAP_CALL(lua_rotate, L, idx, n); +} +SYMBOL_WRAP_DECL(void, lua_copy, lua_State *L, int fromidx, int toidx) { + SYMBOL_WRAP_CALL(lua_copy, L, fromidx, toidx); +} +SYMBOL_WRAP_DECL(int, lua_checkstack, lua_State *L, int sz) { + return SYMBOL_WRAP_CALL(lua_checkstack, L, sz); +} +SYMBOL_WRAP_DECL(void, lua_xmove, lua_State *from, lua_State *to, int n) { + SYMBOL_WRAP_CALL(lua_xmove, from, to, n); +} + + + + + + +SYMBOL_WRAP_DECL(int, lua_isnumber, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_isnumber, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_isstring, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_isstring, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_iscfunction, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_iscfunction, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_isinteger, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_isinteger, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_isuserdata, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_isuserdata, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_type, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_type, L, idx); +} +SYMBOL_WRAP_DECL(const char *, lua_typename, lua_State *L, int tp) { + return SYMBOL_WRAP_CALL(lua_typename, L, tp); +} + +SYMBOL_WRAP_DECL(lua_Number, lua_tonumberx, lua_State *L, int idx, int *isnum) { + return SYMBOL_WRAP_CALL(lua_tonumberx, L, idx, isnum); +} +SYMBOL_WRAP_DECL(lua_Integer, lua_tointegerx, lua_State *L, int idx, int *isnum) { + return SYMBOL_WRAP_CALL(lua_tointegerx, L, idx, isnum); +} +SYMBOL_WRAP_DECL(int, lua_toboolean, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_toboolean, L, idx); +} +SYMBOL_WRAP_DECL(const char *, lua_tolstring, lua_State *L, int idx, size_t *len) { + return SYMBOL_WRAP_CALL(lua_tolstring, L, idx, len); +} +SYMBOL_WRAP_DECL(lua_Unsigned, lua_rawlen, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_rawlen, L, idx); +} +SYMBOL_WRAP_DECL(lua_CFunction, lua_tocfunction, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_tocfunction, L, idx); +} +SYMBOL_WRAP_DECL(void *, lua_touserdata, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_touserdata, L, idx); +} +SYMBOL_WRAP_DECL(lua_State *, lua_tothread, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_tothread, L, idx); +} +SYMBOL_WRAP_DECL(const void *, lua_topointer, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_topointer, L, idx); +} + + + + + + +SYMBOL_WRAP_DECL(void, lua_arith, lua_State *L, int op) { + SYMBOL_WRAP_CALL(lua_arith, L, op); +} + +SYMBOL_WRAP_DECL(int, lua_rawequal, lua_State *L, int idx1, int idx2) { + return SYMBOL_WRAP_CALL(lua_rawequal, L, idx1, idx2); +} +SYMBOL_WRAP_DECL(int, lua_compare, lua_State *L, int idx1, int idx2, int op) { + return SYMBOL_WRAP_CALL(lua_compare, L, idx1, idx2, op); +} + +SYMBOL_WRAP_DECL(void, lua_pushnil, lua_State *L) { + SYMBOL_WRAP_CALL(lua_pushnil, L); +} +SYMBOL_WRAP_DECL(void, lua_pushnumber, lua_State *L, lua_Number n) { + SYMBOL_WRAP_CALL(lua_pushnumber, L, n); +} +SYMBOL_WRAP_DECL(void, lua_pushinteger, lua_State *L, lua_Integer n) { + SYMBOL_WRAP_CALL(lua_pushinteger, L, n); +} +SYMBOL_WRAP_DECL(const char *, lua_pushlstring, lua_State *L, const char *s, size_t l) { + return SYMBOL_WRAP_CALL(lua_pushlstring, L, s, l); +} +SYMBOL_WRAP_DECL(const char *, lua_pushstring, lua_State *L, const char *s) { + return SYMBOL_WRAP_CALL(lua_pushstring, L, s); +} +SYMBOL_WRAP_DECL(const char *, lua_pushvfstring, lua_State *L, const char *fmt, va_list argp) { + return SYMBOL_WRAP_CALL(lua_pushvfstring, L, fmt, argp); +} +SYMBOL_WRAP_DECL(const char *, lua_pushfstring, lua_State *L, const char *fmt, ...) { + const char *res; + va_list argp; + va_start(argp, fmt); + res = lua_pushvfstring(L, fmt, argp); + va_end(argp); + return res; +} +SYMBOL_WRAP_DECL(void, lua_pushcclosure, lua_State *L, lua_CFunction fn, int n) { + SYMBOL_WRAP_CALL(lua_pushcclosure, L, fn, n); +} +SYMBOL_WRAP_DECL(void, lua_pushboolean, lua_State *L, int b) { + SYMBOL_WRAP_CALL(lua_pushboolean, L, b); +} +SYMBOL_WRAP_DECL(void, lua_pushlightuserdata, lua_State *L, void *p) { + SYMBOL_WRAP_CALL(lua_pushlightuserdata, L, p); +} +SYMBOL_WRAP_DECL(int, lua_pushthread, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_pushthread, L); +} + + + + + +SYMBOL_WRAP_DECL(int, lua_getglobal, lua_State *L, const char *var) { + return SYMBOL_WRAP_CALL(lua_getglobal, L, var); +} +SYMBOL_WRAP_DECL(int, lua_gettable, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_gettable, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_getfield, lua_State *L, int idx, const char *k) { + return SYMBOL_WRAP_CALL(lua_getfield, L, idx, k); +} +SYMBOL_WRAP_DECL(int , lua_geti, lua_State *L, int idx, lua_Integer n) { + return SYMBOL_WRAP_CALL(lua_geti, L, idx, n); +} +SYMBOL_WRAP_DECL(int, lua_rawget, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_rawget, L, idx); +} +SYMBOL_WRAP_DECL(int, lua_rawgeti, lua_State *L, int idx, lua_Integer n) { + return SYMBOL_WRAP_CALL(lua_rawgeti, L, idx, n); +} +SYMBOL_WRAP_DECL(int, lua_rawgetp, lua_State *L, int idx, const void *p) { + return SYMBOL_WRAP_CALL(lua_rawgetp, L, idx, p); +} +SYMBOL_WRAP_DECL(void, lua_createtable, lua_State *L, int narr, int nrec) { + SYMBOL_WRAP_CALL(lua_createtable, L, narr, nrec); +} +SYMBOL_WRAP_DECL(void *, lua_newuserdatauv, lua_State *L, size_t sz, int nuvalue) { + return SYMBOL_WRAP_CALL(lua_newuserdatauv, L, sz, nuvalue); +} +SYMBOL_WRAP_DECL(int, lua_getmetatable, lua_State *L, int objindex) { + return SYMBOL_WRAP_CALL(lua_getmetatable, L, objindex); +} +SYMBOL_WRAP_DECL(int, lua_getiuservalue, lua_State *L, int idx, int n) { + return SYMBOL_WRAP_CALL(lua_getiuservalue, L, idx, n); +} + +SYMBOL_WRAP_DECL(void, lua_setglobal, lua_State *L, const char *var) { + SYMBOL_WRAP_CALL(lua_setglobal, L, var); +} +SYMBOL_WRAP_DECL(void, lua_settable, lua_State *L, int idx) { + SYMBOL_WRAP_CALL(lua_settable, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_setfield, lua_State *L, int idx, const char *k) { + SYMBOL_WRAP_CALL(lua_setfield, L, idx, k); +} +SYMBOL_WRAP_DECL(void, lua_seti, lua_State *L, int idx, lua_Integer n) { + SYMBOL_WRAP_CALL(lua_seti, L, idx, n); +} +SYMBOL_WRAP_DECL(void, lua_rawset, lua_State *L, int idx) { + SYMBOL_WRAP_CALL(lua_rawset, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_rawseti, lua_State *L, int idx, lua_Integer n) { + SYMBOL_WRAP_CALL(lua_rawseti, L, idx, n); +} +SYMBOL_WRAP_DECL(void, lua_rawsetp, lua_State *L, int idx, const void *p) { + SYMBOL_WRAP_CALL(lua_rawsetp, L, idx, p); +} +SYMBOL_WRAP_DECL(int, lua_setmetatable, lua_State *L, int objindex) { + return SYMBOL_WRAP_CALL(lua_setmetatable, L, objindex); +} +SYMBOL_WRAP_DECL(int, lua_setiuservalue, lua_State *L, int idx, int n) { + return SYMBOL_WRAP_CALL(lua_setiuservalue, L, idx, n); +} + + + + + +SYMBOL_WRAP_DECL(void, lua_callk, lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k) { + SYMBOL_WRAP_CALL(lua_callk, L, nargs, nresults, ctx, k); +} +SYMBOL_WRAP_DECL(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k) { + return SYMBOL_WRAP_CALL(lua_pcallk, L, nargs, nresults, errfunc, ctx, k); +} +SYMBOL_WRAP_DECL(int, lua_load, lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode) { + return SYMBOL_WRAP_CALL(lua_load, L, reader, dt, chunkname, mode); +} +SYMBOL_WRAP_DECL(int, lua_dump, lua_State *L, lua_Writer writer, void *data, int strip) { + return SYMBOL_WRAP_CALL(lua_dump, L, writer, data, strip); +} + + + + + +SYMBOL_WRAP_DECL(int, lua_yieldk, lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k) { + return SYMBOL_WRAP_CALL(lua_yieldk, L, nresults, ctx, k); +} +SYMBOL_WRAP_DECL(int, lua_resume, lua_State *L, lua_State *from, int narg, int *nres) { + return SYMBOL_WRAP_CALL(lua_resume, L, from, narg, nres); +} +SYMBOL_WRAP_DECL(int, lua_status, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_status, L); +} +SYMBOL_WRAP_DECL(int, lua_isyieldable, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_isyieldable, L); +} + + + + + +SYMBOL_WRAP_DECL(void, lua_setwarnf, lua_State *L, lua_WarnFunction f, void *ud) { + SYMBOL_WRAP_CALL(lua_setwarnf, L, f, ud); +} +SYMBOL_WRAP_DECL(void, lua_warning, lua_State *L, const char *msg, int tocont) { + SYMBOL_WRAP_CALL(lua_warning, L, msg, tocont); +} + + + + + + +SYMBOL_WRAP_DECL(int, lua_gc, lua_State *L, int what, ...) { + /* there are no straightforward ways of passing data. */ + int r; + va_list ap; + va_start(ap, what); + if (what == LUA_GCSTEP) { + int stepsize = va_arg(ap, int); + r = __lua_gc(L, what, stepsize); + } else if (what == LUA_GCINC) { + int pause = va_arg(ap, int); + int stepmul = va_arg(ap, int); + int stepsize = va_arg(ap, int); + r = __lua_gc(L, what, pause, stepmul, stepsize); + } else if (what == LUA_GCGEN) { + int minormul = va_arg(ap, int); + int majormul = va_arg(ap, int); + r = __lua_gc(L, what, minormul, majormul); + } else { + r = __lua_gc(L, what); + } + return r; +} + + + + + + +SYMBOL_WRAP_DECL(int, lua_error, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_error, L); +} + +SYMBOL_WRAP_DECL(int, lua_next, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(lua_next, L, idx); +} + +SYMBOL_WRAP_DECL(void, lua_concat, lua_State *L, int n) { + SYMBOL_WRAP_CALL(lua_concat, L, n); +} +SYMBOL_WRAP_DECL(void, lua_len, lua_State *L, int idx) { + SYMBOL_WRAP_CALL(lua_len, L, idx); +} + +SYMBOL_WRAP_DECL(size_t, lua_stringtonumber, lua_State *L, const char *s) { + return SYMBOL_WRAP_CALL(lua_stringtonumber, L, s); +} + +SYMBOL_WRAP_DECL(lua_Alloc, lua_getallocf, lua_State *L, void **ud) { + return SYMBOL_WRAP_CALL(lua_getallocf, L, ud); +} +SYMBOL_WRAP_DECL(void, lua_setallocf, lua_State *L, lua_Alloc f, void *ud) { + SYMBOL_WRAP_CALL(lua_setallocf, L, f, ud); +} + +SYMBOL_WRAP_DECL(void, lua_toclose, lua_State *L, int idx) { + SYMBOL_WRAP_CALL(lua_toclose, L, idx); +} +SYMBOL_WRAP_DECL(void, lua_closeslot, lua_State *L, int idx) { + SYMBOL_WRAP_CALL(lua_closeslot, L, idx); +} + + + + + + +SYMBOL_WRAP_DECL(int, lua_getstack, lua_State *L, int level, lua_Debug *ar) { + return SYMBOL_WRAP_CALL(lua_getstack, L, level, ar); +} +SYMBOL_WRAP_DECL(int, lua_getinfo, lua_State *L, const char *what, lua_Debug *ar) { + return SYMBOL_WRAP_CALL(lua_getinfo, L, what, ar); +} +SYMBOL_WRAP_DECL(const char *, lua_getlocal, lua_State *L, const lua_Debug *ar, int n) { + return SYMBOL_WRAP_CALL(lua_getlocal, L, ar, n); +} +SYMBOL_WRAP_DECL(const char *, lua_setlocal, lua_State *L, const lua_Debug *ar, int n) { + return SYMBOL_WRAP_CALL(lua_setlocal, L, ar, n); +} +SYMBOL_WRAP_DECL(const char *, lua_getupvalue, lua_State *L, int funcindex, int n) { + return SYMBOL_WRAP_CALL(lua_getupvalue, L, funcindex, n); +} +SYMBOL_WRAP_DECL(const char *, lua_setupvalue, lua_State *L, int funcindex, int n) { + return SYMBOL_WRAP_CALL(lua_setupvalue, L, funcindex, n); +} + +SYMBOL_WRAP_DECL(void *, lua_upvalueid, lua_State *L, int fidx, int n) { + return SYMBOL_WRAP_CALL(lua_upvalueid, L, fidx, n); +} +SYMBOL_WRAP_DECL(void, lua_upvaluejoin, lua_State *L, int fidx1, int n1, int fidx2, int n2) { + SYMBOL_WRAP_CALL(lua_upvaluejoin, L, fidx1, n1, fidx2, n2); +} + +SYMBOL_WRAP_DECL(void, lua_sethook, lua_State *L, lua_Hook func, int mask, int count) { + SYMBOL_WRAP_CALL(lua_sethook, L, func, mask, count); +} +SYMBOL_WRAP_DECL(lua_Hook, lua_gethook, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_gethook, L); +} +SYMBOL_WRAP_DECL(int, lua_gethookmask, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_gethookmask, L); +} +SYMBOL_WRAP_DECL(int, lua_gethookcount, lua_State *L) { + return SYMBOL_WRAP_CALL(lua_gethookcount, L); +} + +SYMBOL_WRAP_DECL(int, lua_setcstacklimit, lua_State *L, unsigned int limit) { + return SYMBOL_WRAP_CALL(lua_setcstacklimit, L, limit); +} + + + + + + +SYMBOL_WRAP_DECL(void, luaL_checkversion_, lua_State *L, lua_Number ver, size_t sz) { + SYMBOL_WRAP_CALL(luaL_checkversion_, L, ver, sz); +} +SYMBOL_WRAP_DECL(int, luaL_getmetafield, lua_State *L, int obj, const char *e) { + return SYMBOL_WRAP_CALL(luaL_getmetafield, L, obj, e); +} +SYMBOL_WRAP_DECL(int, luaL_callmeta, lua_State *L, int obj, const char *e) { + return SYMBOL_WRAP_CALL(luaL_callmeta, L, obj, e); +} +SYMBOL_WRAP_DECL(const char *, luaL_tolstring, lua_State *L, int idx, size_t *len) { + return SYMBOL_WRAP_CALL(luaL_tolstring, L, idx, len); +} +SYMBOL_WRAP_DECL(int, luaL_argerror, lua_State *L, int numarg, const char *extramsg) { + return SYMBOL_WRAP_CALL(luaL_argerror, L, numarg, extramsg); +} +SYMBOL_WRAP_DECL(int, luaL_typeerror, lua_State *L, int arg, const char *tname) { + return SYMBOL_WRAP_CALL(luaL_typeerror, L, arg, tname); +} +SYMBOL_WRAP_DECL(const char *, luaL_checklstring, lua_State *L, int numArg, size_t *l) { + return SYMBOL_WRAP_CALL(luaL_checklstring, L, numArg, l); +} +SYMBOL_WRAP_DECL(const char *, luaL_optlstring, lua_State *L, int numArg, const char *def, size_t *l) { + return SYMBOL_WRAP_CALL(luaL_optlstring, L, numArg, def, l); +} +SYMBOL_WRAP_DECL(lua_Number, luaL_checknumber, lua_State *L, int numArg) { + return SYMBOL_WRAP_CALL(luaL_checknumber, L, numArg); +} +SYMBOL_WRAP_DECL(lua_Number, luaL_optnumber, lua_State *L, int nArg, lua_Number def) { + return SYMBOL_WRAP_CALL(luaL_optnumber, L, nArg, def); +} + +SYMBOL_WRAP_DECL(lua_Integer, luaL_checkinteger, lua_State *L, int numArg) { + return SYMBOL_WRAP_CALL(luaL_checkinteger, L, numArg); +} +SYMBOL_WRAP_DECL(lua_Integer, luaL_optinteger, lua_State *L, int nArg, lua_Integer def) { + return SYMBOL_WRAP_CALL(luaL_optinteger, L, nArg, def); +} + +SYMBOL_WRAP_DECL(void, luaL_checkstack, lua_State *L, int sz, const char *msg) { + SYMBOL_WRAP_CALL(luaL_checkstack, L, sz, msg); +} +SYMBOL_WRAP_DECL(void, luaL_checktype, lua_State *L, int narg, int t) { + SYMBOL_WRAP_CALL(luaL_checktype, L, narg, t); +} +SYMBOL_WRAP_DECL(void, luaL_checkany, lua_State *L, int narg) { + SYMBOL_WRAP_CALL(luaL_checkany, L, narg); +} +SYMBOL_WRAP_DECL(int, luaL_newmetatable, lua_State *L, const char *tname) { + return SYMBOL_WRAP_CALL(luaL_newmetatable, L, tname); +} +SYMBOL_WRAP_DECL(void, luaL_setmetatable, lua_State *L, const char *tname) { + SYMBOL_WRAP_CALL(luaL_setmetatable, L, tname); +} +SYMBOL_WRAP_DECL(void *, luaL_testudata, lua_State *L, int ud, const char *tname) { + return SYMBOL_WRAP_CALL(luaL_testudata, L, ud, tname); +} +SYMBOL_WRAP_DECL(void *, luaL_checkudata, lua_State *L, int ud, const char *tname) { + return SYMBOL_WRAP_CALL(luaL_checkudata, L, ud, tname); +} + +SYMBOL_WRAP_DECL(void, luaL_where, lua_State *L, int lvl) { + SYMBOL_WRAP_CALL(luaL_where, L, lvl); +} +SYMBOL_WRAP_DECL(int, luaL_error, lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + +SYMBOL_WRAP_DECL(int, luaL_checkoption, lua_State *L, int narg, const char *def, const char *const lst[]) { + return SYMBOL_WRAP_CALL(luaL_checkoption, L, narg, def, lst); +} + +SYMBOL_WRAP_DECL(int, luaL_fileresult, lua_State *L, int stat, const char *fname) { + return SYMBOL_WRAP_CALL(luaL_fileresult, L, stat, fname); +} +SYMBOL_WRAP_DECL(int, luaL_execresult, lua_State *L, int stat) { + return SYMBOL_WRAP_CALL(luaL_execresult, L, stat); +} + + + + + + +SYMBOL_WRAP_DECL(int, luaL_ref, lua_State *L, int t) { + return SYMBOL_WRAP_CALL(luaL_ref, L, t); +} +SYMBOL_WRAP_DECL(void, luaL_unref, lua_State *L, int t, int ref) { + SYMBOL_WRAP_CALL(luaL_unref, L, t, ref); +} + +SYMBOL_WRAP_DECL(int, luaL_loadfilex, lua_State *L, const char *filename, const char *mode) { + return SYMBOL_WRAP_CALL(luaL_loadfilex, L, filename, mode); +} + +SYMBOL_WRAP_DECL(int, luaL_loadbufferx, lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) { + return SYMBOL_WRAP_CALL(luaL_loadbufferx, L, buff, sz, name, mode); +} + +SYMBOL_WRAP_DECL(int, luaL_loadstring, lua_State *L, const char *s) { + return SYMBOL_WRAP_CALL(luaL_loadstring, L, s); +} + +SYMBOL_WRAP_DECL(lua_State *, luaL_newstate, void) { + return __luaL_newstate(); +} +SYMBOL_WRAP_DECL(lua_Integer, luaL_len, lua_State *L, int idx) { + return SYMBOL_WRAP_CALL(luaL_len, L, idx); +} + +SYMBOL_WRAP_DECL(void, luaL_addgsub, luaL_Buffer *b, const char *s, + const char *p, const char *r) { + SYMBOL_WRAP_CALL(luaL_addgsub, b, s, p, r); +} +SYMBOL_WRAP_DECL(const char *, luaL_gsub, lua_State *L, const char *s, const char *p, const char *r) { + return SYMBOL_WRAP_CALL(luaL_gsub, L, s, p, r); +} + +SYMBOL_WRAP_DECL(void, luaL_setfuncs, lua_State *L, const luaL_Reg *l, int nup) { + SYMBOL_WRAP_CALL(luaL_setfuncs, L, l, nup); +} + +SYMBOL_WRAP_DECL(int, luaL_getsubtable, lua_State *L, int idx, const char *fname) { + return SYMBOL_WRAP_CALL(luaL_getsubtable, L, idx, fname); +} + +SYMBOL_WRAP_DECL(void, luaL_traceback, lua_State *L, lua_State *L1, const char *msg, int level) { + SYMBOL_WRAP_CALL(luaL_traceback, L, L1, msg, level); +} + +SYMBOL_WRAP_DECL(void, luaL_requiref, lua_State *L, const char *modname, lua_CFunction openf, int glb) { + SYMBOL_WRAP_CALL(luaL_requiref, L, modname, openf, glb); +} + + + + + + +SYMBOL_WRAP_DECL(void, luaL_buffinit, lua_State *L, luaL_Buffer *B) { + SYMBOL_WRAP_CALL(luaL_buffinit, L, B); +} +SYMBOL_WRAP_DECL(char *, luaL_prepbuffsize, luaL_Buffer *B, size_t sz) { + return SYMBOL_WRAP_CALL(luaL_prepbuffsize, B, sz); +} +SYMBOL_WRAP_DECL(void, luaL_addlstring, luaL_Buffer *B, const char *s, size_t l) { + SYMBOL_WRAP_CALL(luaL_addlstring, B, s, l); +} +SYMBOL_WRAP_DECL(void, luaL_addstring, luaL_Buffer *B, const char *s) { + SYMBOL_WRAP_CALL(luaL_addstring, B, s); +} +SYMBOL_WRAP_DECL(void, luaL_addvalue, luaL_Buffer *B) { + SYMBOL_WRAP_CALL(luaL_addvalue, B); +} +SYMBOL_WRAP_DECL(void, luaL_pushresult, luaL_Buffer *B) { + SYMBOL_WRAP_CALL(luaL_pushresult, B); +} +SYMBOL_WRAP_DECL(void, luaL_pushresultsize, luaL_Buffer *B, size_t sz) { + SYMBOL_WRAP_CALL(luaL_pushresultsize, B, sz); +} +SYMBOL_WRAP_DECL(char *, luaL_buffinitsize, lua_State *L, luaL_Buffer *B, size_t sz) { + return SYMBOL_WRAP_CALL(luaL_buffinitsize, L, B, sz); +} + +SYMBOL_WRAP_DECL(int, luaopen_base, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_base, L); +} + +SYMBOL_WRAP_DECL(int, luaopen_coroutine, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_coroutine, L); +} + +SYMBOL_WRAP_DECL(int, luaopen_table, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_table, L); +} + +SYMBOL_WRAP_DECL(int, luaopen_io, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_io, L); +} + +SYMBOL_WRAP_DECL(int, luaopen_os, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_os, L); +} + +SYMBOL_WRAP_DECL(int, luaopen_string, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_string, L); +} + +SYMBOL_WRAP_DECL(int, luaopen_utf8, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_utf8, L); +} + +SYMBOL_WRAP_DECL(int, luaopen_math, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_math, L); +} + +SYMBOL_WRAP_DECL(int, luaopen_debug, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_debug, L); +} + +SYMBOL_WRAP_DECL(int, luaopen_package, lua_State *L) { + return SYMBOL_WRAP_CALL(luaopen_package, L); +} + +SYMBOL_WRAP_DECL(void, luaL_openlibs, lua_State *L) { + SYMBOL_WRAP_CALL(luaL_openlibs, L); +} + + + + + + +#define IMPORT_SYMBOL(name, ret, ...) \ + __##name = (\ + (*(void **) (&__##name) = symbol(#name)), \ + __##name == NULL ? ((ret (*) (__VA_ARGS__)) &__lite_xl_fallback_##name) : __##name\ + ) + +void lite_xl_plugin_init(void *XL) { + void* (*symbol)(const char *); + *(void **) (&symbol) = XL; + IMPORT_SYMBOL(lua_newstate, lua_State *, lua_Alloc f, void *ud); + IMPORT_SYMBOL(lua_close, void, lua_State *L); + IMPORT_SYMBOL(lua_newthread, lua_State *, lua_State *L); + IMPORT_SYMBOL(lua_resetthread, int, lua_State *L); + IMPORT_SYMBOL(lua_atpanic, lua_CFunction, lua_State *L, lua_CFunction panicf); + IMPORT_SYMBOL(lua_version, lua_Number, lua_State *L); + IMPORT_SYMBOL(lua_absindex, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_gettop, int, lua_State *L); + IMPORT_SYMBOL(lua_settop, void, lua_State *L, int idx); + IMPORT_SYMBOL(lua_pushvalue, void, lua_State *L, int idx); + IMPORT_SYMBOL(lua_rotate, void, lua_State *L, int idx, int n); + IMPORT_SYMBOL(lua_copy, void, lua_State *L, int fromidx, int toidx); + IMPORT_SYMBOL(lua_checkstack, int, lua_State *L, int sz); + IMPORT_SYMBOL(lua_xmove, void, lua_State *from, lua_State *to, int n); + IMPORT_SYMBOL(lua_isnumber, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_isstring, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_iscfunction, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_isinteger, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_isuserdata, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_type, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_typename, const char *, lua_State *L, int tp); + IMPORT_SYMBOL(lua_tonumberx, lua_Number, lua_State *L, int idx, int *isnum); + IMPORT_SYMBOL(lua_tointegerx, lua_Integer, lua_State *L, int idx, int *isnum); + IMPORT_SYMBOL(lua_toboolean, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_tolstring, const char *, lua_State *L, int idx, size_t *len); + IMPORT_SYMBOL(lua_rawlen, lua_Unsigned, lua_State *L, int idx); + IMPORT_SYMBOL(lua_tocfunction, lua_CFunction, lua_State *L, int idx); + IMPORT_SYMBOL(lua_touserdata, void *, lua_State *L, int idx); + IMPORT_SYMBOL(lua_tothread, lua_State *, lua_State *L, int idx); + IMPORT_SYMBOL(lua_topointer, const void *, lua_State *L, int idx); + IMPORT_SYMBOL(lua_arith, void, lua_State *L, int op); + IMPORT_SYMBOL(lua_rawequal, int, lua_State *L, int idx1, int idx2); + IMPORT_SYMBOL(lua_compare, int, lua_State *L, int idx1, int idx2, int op); + IMPORT_SYMBOL(lua_pushnil, void, lua_State *L); + IMPORT_SYMBOL(lua_pushnumber, void, lua_State *L, lua_Number n); + IMPORT_SYMBOL(lua_pushinteger, void, lua_State *L, lua_Integer n); + IMPORT_SYMBOL(lua_pushlstring, const char *, lua_State *L, const char *s, size_t l); + IMPORT_SYMBOL(lua_pushstring, const char *, lua_State *L, const char *s); + IMPORT_SYMBOL(lua_pushvfstring, const char *, lua_State *L, const char *fmt, va_list argp); + IMPORT_SYMBOL(lua_pushfstring, const char *, lua_State *L, const char *fmt, ...); + IMPORT_SYMBOL(lua_pushcclosure, void, lua_State *L, lua_CFunction fn, int n); + IMPORT_SYMBOL(lua_pushboolean, void, lua_State *L, int b); + IMPORT_SYMBOL(lua_pushlightuserdata, void, lua_State *L, void *p); + IMPORT_SYMBOL(lua_pushthread, int, lua_State *L); + IMPORT_SYMBOL(lua_getglobal, int, lua_State *L, const char *var); + IMPORT_SYMBOL(lua_gettable, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_getfield, int, lua_State *L, int idx, const char *k); + IMPORT_SYMBOL(lua_geti, int, lua_State *L, int idx, lua_Integer n); + IMPORT_SYMBOL(lua_rawget, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_rawgeti, int, lua_State *L, int idx, lua_Integer n); + IMPORT_SYMBOL(lua_rawgetp, int, lua_State *L, int idx, const void *p); + IMPORT_SYMBOL(lua_createtable, void, lua_State *L, int narr, int nrec); + IMPORT_SYMBOL(lua_newuserdatauv, void *, lua_State *L, size_t sz, int nuvalue); + IMPORT_SYMBOL(lua_getmetatable, int, lua_State *L, int objindex); + IMPORT_SYMBOL(lua_getiuservalue, int, lua_State *L, int idx, int n); + IMPORT_SYMBOL(lua_setglobal, void, lua_State *L, const char *var); + IMPORT_SYMBOL(lua_settable, void, lua_State *L, int idx); + IMPORT_SYMBOL(lua_setfield, void, lua_State *L, int idx, const char *k); + IMPORT_SYMBOL(lua_seti, void, lua_State *L, int idx, lua_Integer n); + IMPORT_SYMBOL(lua_rawset, void, lua_State *L, int idx); + IMPORT_SYMBOL(lua_rawseti, void, lua_State *L, int idx, lua_Integer n); + IMPORT_SYMBOL(lua_rawsetp, void, lua_State *L, int idx, const void *p); + IMPORT_SYMBOL(lua_setmetatable, int, lua_State *L, int objindex); + IMPORT_SYMBOL(lua_setiuservalue, int, lua_State *L, int idx, int n); + IMPORT_SYMBOL(lua_callk, void, lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k); + IMPORT_SYMBOL(lua_pcallk, int, lua_State *L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k); + IMPORT_SYMBOL(lua_load, int, lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); + IMPORT_SYMBOL(lua_dump, int, lua_State *L, lua_Writer writer, void *data, int strip); + IMPORT_SYMBOL(lua_yieldk, int, lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k); + IMPORT_SYMBOL(lua_resume, int, lua_State *L, lua_State *from, int narg, int *nres); + IMPORT_SYMBOL(lua_status, int, lua_State *L); + IMPORT_SYMBOL(lua_isyieldable, int, lua_State *L); + IMPORT_SYMBOL(lua_setwarnf, void, lua_State *L, lua_WarnFunction f, void *ud); + IMPORT_SYMBOL(lua_warning, void, lua_State *L, const char *msg, int tocont); + IMPORT_SYMBOL(lua_gc, int, lua_State *L, int what, ...); + IMPORT_SYMBOL(lua_error, int, lua_State *L); + IMPORT_SYMBOL(lua_next, int, lua_State *L, int idx); + IMPORT_SYMBOL(lua_concat, void, lua_State *L, int n); + IMPORT_SYMBOL(lua_len, void, lua_State *L, int idx); + IMPORT_SYMBOL(lua_stringtonumber, size_t, lua_State *L, const char *s); + IMPORT_SYMBOL(lua_getallocf, lua_Alloc, lua_State *L, void **ud); + IMPORT_SYMBOL(lua_setallocf, void, lua_State *L, lua_Alloc f, void *ud); + IMPORT_SYMBOL(lua_toclose, void, lua_State *L, int idx); + IMPORT_SYMBOL(lua_closeslot, void, lua_State *L, int idx); + IMPORT_SYMBOL(lua_getstack, int, lua_State *L, int level, lua_Debug *ar); + IMPORT_SYMBOL(lua_getinfo, int, lua_State *L, const char *what, lua_Debug *ar); + IMPORT_SYMBOL(lua_getlocal, const char *, lua_State *L, const lua_Debug *ar, int n); + IMPORT_SYMBOL(lua_setlocal, const char *, lua_State *L, const lua_Debug *ar, int n); + IMPORT_SYMBOL(lua_getupvalue, const char *, lua_State *L, int funcindex, int n); + IMPORT_SYMBOL(lua_setupvalue, const char *, lua_State *L, int funcindex, int n); + IMPORT_SYMBOL(lua_upvalueid, void *, lua_State *L, int fidx, int n); + IMPORT_SYMBOL(lua_upvaluejoin, void, lua_State *L, int fidx1, int n1, int fidx2, int n2); + IMPORT_SYMBOL(lua_sethook, void, lua_State *L, lua_Hook func, int mask, int count); + IMPORT_SYMBOL(lua_gethook, lua_Hook, lua_State *L); + IMPORT_SYMBOL(lua_gethookmask, int, lua_State *L); + IMPORT_SYMBOL(lua_gethookcount, int, lua_State *L); + IMPORT_SYMBOL(lua_setcstacklimit, int, lua_State *L, unsigned int limit); + IMPORT_SYMBOL(luaL_checkversion_, void, lua_State *L, lua_Number ver, size_t sz); + IMPORT_SYMBOL(luaL_getmetafield, int, lua_State *L, int obj, const char *e); + IMPORT_SYMBOL(luaL_callmeta, int, lua_State *L, int obj, const char *e); + IMPORT_SYMBOL(luaL_tolstring, const char *, lua_State *L, int idx, size_t *len); + IMPORT_SYMBOL(luaL_argerror, int, lua_State *L, int numarg, const char *extramsg); + IMPORT_SYMBOL(luaL_typeerror, int, lua_State *L, int arg, const char *tname); + IMPORT_SYMBOL(luaL_checklstring, const char *, lua_State *L, int numArg, size_t *l); + IMPORT_SYMBOL(luaL_optlstring, const char *, lua_State *L, int numArg, const char *def, size_t *l); + IMPORT_SYMBOL(luaL_checknumber, lua_Number, lua_State *L, int numArg); + IMPORT_SYMBOL(luaL_optnumber, lua_Number, lua_State *L, int nArg, lua_Number def); + IMPORT_SYMBOL(luaL_checkinteger, lua_Integer, lua_State *L, int numArg); + IMPORT_SYMBOL(luaL_optinteger, lua_Integer, lua_State *L, int nArg, lua_Integer def); + IMPORT_SYMBOL(luaL_checkstack, void, lua_State *L, int sz, const char *msg); + IMPORT_SYMBOL(luaL_checktype, void, lua_State *L, int narg, int t); + IMPORT_SYMBOL(luaL_checkany, void, lua_State *L, int narg); + IMPORT_SYMBOL(luaL_newmetatable, int, lua_State *L, const char *tname); + IMPORT_SYMBOL(luaL_setmetatable, void, lua_State *L, const char *tname); + IMPORT_SYMBOL(luaL_testudata, void *, lua_State *L, int ud, const char *tname); + IMPORT_SYMBOL(luaL_checkudata, void *, lua_State *L, int ud, const char *tname); + IMPORT_SYMBOL(luaL_where, void, lua_State *L, int lvl); + IMPORT_SYMBOL(luaL_error, int, lua_State *L, const char *fmt, ...); + IMPORT_SYMBOL(luaL_checkoption, int, lua_State *L, int narg, const char *def, const char *const lst[]); + IMPORT_SYMBOL(luaL_fileresult, int, lua_State *L, int stat, const char *fname); + IMPORT_SYMBOL(luaL_execresult, int, lua_State *L, int stat); + IMPORT_SYMBOL(luaL_ref, int, lua_State *L, int t); + IMPORT_SYMBOL(luaL_unref, void, lua_State *L, int t, int ref); + IMPORT_SYMBOL(luaL_loadfilex, int, lua_State *L, const char *filename, const char *mode); + IMPORT_SYMBOL(luaL_loadbufferx, int, lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); + IMPORT_SYMBOL(luaL_loadstring, int, lua_State *L, const char *s); + IMPORT_SYMBOL(luaL_newstate, lua_State *, void); + IMPORT_SYMBOL(luaL_len, lua_Integer, lua_State *L, int idx); + IMPORT_SYMBOL(luaL_addgsub, void, luaL_Buffer *b, const char *s, const char *p, const char *r); + IMPORT_SYMBOL(luaL_gsub, const char *, lua_State *L, const char *s, const char *p, const char *r); + IMPORT_SYMBOL(luaL_setfuncs, void, lua_State *L, const luaL_Reg *l, int nup); + IMPORT_SYMBOL(luaL_getsubtable, int, lua_State *L, int idx, const char *fname); + IMPORT_SYMBOL(luaL_traceback, void, lua_State *L, lua_State *L1, const char *msg, int level); + IMPORT_SYMBOL(luaL_requiref, void, lua_State *L, const char *modname, lua_CFunction openf, int glb); + IMPORT_SYMBOL(luaL_buffinit, void, lua_State *L, luaL_Buffer *B); + IMPORT_SYMBOL(luaL_prepbuffsize, char *, luaL_Buffer *B, size_t sz); + IMPORT_SYMBOL(luaL_addlstring, void, luaL_Buffer *B, const char *s, size_t l); + IMPORT_SYMBOL(luaL_addstring, void, luaL_Buffer *B, const char *s); + IMPORT_SYMBOL(luaL_addvalue, void, luaL_Buffer *B); + IMPORT_SYMBOL(luaL_pushresult, void, luaL_Buffer *B); + IMPORT_SYMBOL(luaL_pushresultsize, void, luaL_Buffer *B, size_t sz); + IMPORT_SYMBOL(luaL_buffinitsize, char *, lua_State *L, luaL_Buffer *B, size_t sz); + IMPORT_SYMBOL(luaopen_base, int, lua_State *L); + IMPORT_SYMBOL(luaopen_coroutine, int, lua_State *L); + IMPORT_SYMBOL(luaopen_table, int, lua_State *L); + IMPORT_SYMBOL(luaopen_io, int, lua_State *L); + IMPORT_SYMBOL(luaopen_os, int, lua_State *L); + IMPORT_SYMBOL(luaopen_string, int, lua_State *L); + IMPORT_SYMBOL(luaopen_utf8, int, lua_State *L); + IMPORT_SYMBOL(luaopen_math, int, lua_State *L); + IMPORT_SYMBOL(luaopen_debug, int, lua_State *L); + IMPORT_SYMBOL(luaopen_package, int, lua_State *L); + IMPORT_SYMBOL(luaL_openlibs, void, lua_State* L); +} + +#undef IMPORT_SYMBOL +#undef IMPORT_SYMBOL_OPT + +#else /* LITE_XL_PLUGIN_ENTRYPOINT */ + +void lite_xl_plugin_init(void *XL); + +#endif /* LITE_XL_PLUGIN_ENTRYPOINT */ + +#undef LITE_XL_API +#undef SYMBOL_WRAP_DECL +#undef SYMBOL_WRAP_CALL +#undef SYMBOL_WRAP_CALL_FB +#undef SYMBOL_DECLARE +#undef SYMBOL_DECLARE_VARARG +#undef UNUSED +#undef CONCAT +#undef CONCAT1 +#undef CONCAT2 +#undef FE_1 +#undef FE_2 +#undef FE_3 +#undef FE_4 +#undef FE_5 +#undef FE_6 +#undef FE_7 +#undef FE_8 +#undef FOR_EACH_NARG +#undef FOR_EACH_NARG_ +#undef FOR_EACH_ARG_N +#undef FOR_EACH_RSEQ_N +#undef FOR_EACH_ +#undef FOR_EACH + +#endif /* LITE_XL_PLUGIN_API */ + +/****************************************************************************** +* Copyright (C) 1994-2023 Lua.org, PUC-Rio; Lite XL contributors. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ \ No newline at end of file diff --git a/resources/lite_xl_plugin_api.h b/resources/lite_xl_plugin_api.h deleted file mode 100644 index 8bf74054..00000000 --- a/resources/lite_xl_plugin_api.h +++ /dev/null @@ -1,1124 +0,0 @@ -#ifndef LITE_XL_PLUGIN_API -#define LITE_XL_PLUGIN_API -/** -The lite_xl plugin API is quite simple. Any shared library can be a plugin file, so long -as it has an entrypoint that looks like the following, where xxxxx is the plugin name: - -#define LITE_XL_PLUGIN_ENTRYPOINT -#include "lite_xl_plugin_api.h" -int luaopen_lite_xl_xxxxx(lua_State* L, void* XL) { - lite_xl_plugin_init(XL); - ... - return 1; -} - -NOTE: `#define LITE_XL_PLUGIN_ENTRYPOINT` needs to be defined only on the -source file where the lite_xl_plugin_init() initialization function is called. - -In linux, to compile this file, you'd do: 'gcc -o xxxxx.so -shared xxxxx.c'. Simple! -Due to the way the API is structured, you *should not* link or include lua libraries. -This file was automatically generated. DO NOT MODIFY DIRECTLY. - -UNLESS you're us, and you had to modify this file manually to get it ready for 2.1. - -Go figure. - -**/ - - -#include -#include // for BUFSIZ? this is kinda weird -#include - -#define SYMBOL_WRAP_DECL(ret, name, ...) \ - ret name(__VA_ARGS__) - -#define SYMBOL_WRAP_CALL(name, ...) \ - return __##name(__VA_ARGS__) - -#define SYMBOL_WRAP_CALL_FB(name, ...) \ - return __lite_xl_fallback_##name(__VA_ARGS__) - -#ifdef LITE_XL_PLUGIN_ENTRYPOINT - #define SYMBOL_DECLARE(ret, name, ...) \ - static ret (*__##name) (__VA_ARGS__); \ - SYMBOL_WRAP_DECL(ret, name, __VA_ARGS__); \ - static ret __lite_xl_fallback_##name(__VA_ARGS__) { \ - fputs("warning: " #name " is a stub", stderr); \ - exit(1); \ - } -#else - #define SYMBOL_DECLARE(ret, name, ...) \ - SYMBOL_WRAP_DECL(ret, name, __VA_ARGS__); -#endif - -/** luaconf.h **/ - -#ifndef lconfig_h -#define lconfig_h -#include -#include -#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__) -#define LUA_ANSI -#endif -#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE) -#define LUA_WIN -#endif -#if defined(LUA_WIN) -#define LUA_DL_DLL -#define LUA_USE_AFORMAT -#endif -#if defined(LUA_USE_LINUX) -#define LUA_USE_POSIX -#define LUA_USE_DLOPEN -#define LUA_USE_READLINE -#define LUA_USE_STRTODHEX -#define LUA_USE_AFORMAT -#define LUA_USE_LONGLONG -#endif -#if defined(LUA_USE_MACOSX) -#define LUA_USE_POSIX -#define LUA_USE_DLOPEN -#define LUA_USE_READLINE -#define LUA_USE_STRTODHEX -#define LUA_USE_AFORMAT -#define LUA_USE_LONGLONG -#endif -#if defined(LUA_USE_POSIX) -#define LUA_USE_MKSTEMP -#define LUA_USE_ISATTY -#define LUA_USE_POPEN -#define LUA_USE_ULONGJMP -#define LUA_USE_GMTIME_R -#endif -#if defined(_WIN32) -#define LUA_LDIR "!\\lua\\" -#define LUA_CDIR "!\\" -#define LUA_PATH_DEFAULT LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua" -#define LUA_CPATH_DEFAULT LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" -#else -#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/" -#define LUA_ROOT "/usr/local/" -#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR -#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR -#define LUA_PATH_DEFAULT LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" -#define LUA_CPATH_DEFAULT LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" -#endif -#if defined(_WIN32) -#define LUA_DIRSEP "\\" -#else -#define LUA_DIRSEP "/" -#endif -#define LUA_ENV "_ENV" -#if defined(LUA_BUILD_AS_DLL) -#if defined(LUA_CORE) || defined(LUA_LIB) -#define LUA_API __declspec(dllexport) -#else -#define LUA_API __declspec(dllimport) -#endif -#else -#define LUA_API extern -#endif -#define LUALIB_API LUA_API -#define LUAMOD_API LUALIB_API -#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && defined(__ELF__) -#define LUAI_FUNC __attribute__((visibility("hidden"))) extern -#define LUAI_DDEC LUAI_FUNC -#define LUAI_DDEF -#else -#define LUAI_FUNC extern -#define LUAI_DDEC extern -#define LUAI_DDEF -#endif -#define LUA_QL(x) "'" x "'" -#define LUA_QS LUA_QL("%s") -#define LUA_IDSIZE 60 -#if defined(LUA_LIB) || defined(lua_c) -#include -#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) -#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout)) -#endif -#define luai_writestringerror(s,p) (fprintf(stderr, (s), (p)), fflush(stderr)) -#define LUAI_MAXSHORTLEN 40 -#if defined(LUA_COMPAT_ALL) -#define LUA_COMPAT_UNPACK -#define LUA_COMPAT_LOADERS -#define lua_cpcall(L,f,u) (lua_pushcfunction(L, (f)), lua_pushlightuserdata(L,(u)), lua_pcall(L,1,0,0)) -#define LUA_COMPAT_LOG10 -#define LUA_COMPAT_LOADSTRING -#define LUA_COMPAT_MAXN -#define lua_strlen(L,i) lua_rawlen(L, (i)) -#define lua_objlen(L,i) lua_rawlen(L, (i)) -#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) -#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) -#define LUA_COMPAT_MODULE -#endif -#if INT_MAX-20 < 32760 -#define LUAI_BITSINT 16 -#elif INT_MAX > 2147483640L -#define LUAI_BITSINT 32 -#else -#error "you must define LUA_BITSINT with number of bits in an integer" -#endif -#if LUAI_BITSINT >= 32 -#define LUA_INT32 int -#define LUAI_UMEM size_t -#define LUAI_MEM ptrdiff_t -#else -#define LUA_INT32 long -#define LUAI_UMEM unsigned long -#define LUAI_MEM long -#endif -#if LUAI_BITSINT >= 32 -#define LUAI_MAXSTACK 1000000 -#else -#define LUAI_MAXSTACK 15000 -#endif -#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000) -#define LUAL_BUFFERSIZE BUFSIZ -#define LUA_NUMBER_DOUBLE -#define LUA_NUMBER double -#define LUAI_UACNUMBER double -#define LUA_NUMBER_SCAN "%lf" -#define LUA_NUMBER_FMT "%.14g" -#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) -#define LUAI_MAXNUMBER2STR 32 -#define l_mathop(x) (x) -#define lua_str2number(s,p) strtod((s), (p)) -#if defined(LUA_USE_STRTODHEX) -#define lua_strx2number(s,p) strtod((s), (p)) -#endif -#if defined(lobject_c) || defined(lvm_c) -#include -#define luai_nummod(L,a,b) ((a) - l_mathop(floor)((a)/(b))*(b)) -#define luai_numpow(L,a,b) (l_mathop(pow)(a,b)) -#endif -#if defined(LUA_CORE) -#define luai_numadd(L,a,b) ((a)+(b)) -#define luai_numsub(L,a,b) ((a)-(b)) -#define luai_nummul(L,a,b) ((a)*(b)) -#define luai_numdiv(L,a,b) ((a)/(b)) -#define luai_numunm(L,a) (-(a)) -#define luai_numeq(a,b) ((a)==(b)) -#define luai_numlt(L,a,b) ((a)<(b)) -#define luai_numle(L,a,b) ((a)<=(b)) -#define luai_numisnan(L,a) (!luai_numeq((a), (a))) -#endif -#define LUA_INTEGER ptrdiff_t -#define LUA_KCONTEXT ptrdiff_t -#define LUA_UNSIGNED unsigned LUA_INT32 -#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) -#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) -#define LUA_MSASMTRICK -#define LUA_IEEEENDIAN 0 -#define LUA_NANTRICK -#elif defined(__i386__) || defined(__i386) || defined(__X86__) -#define LUA_IEEE754TRICK -#define LUA_IEEELL -#define LUA_IEEEENDIAN 0 -#define LUA_NANTRICK -#elif defined(__x86_64) -#define LUA_IEEE754TRICK -#define LUA_IEEEENDIAN 0 -#elif defined(__POWERPC__) || defined(__ppc__) -#define LUA_IEEE754TRICK -#define LUA_IEEEENDIAN 1 -#else -#define LUA_IEEE754TRICK -#endif -#endif -#endif - -/** lua.h **/ - -typedef struct lua_State lua_State; -typedef int (*lua_CFunction) (lua_State *L); -typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); -typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); -typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); -typedef LUA_KCONTEXT lua_KContext; -typedef LUA_NUMBER lua_Number; -typedef LUA_INTEGER lua_Integer; -typedef LUA_UNSIGNED lua_Unsigned; -typedef struct lua_Debug lua_Debug; -typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); -typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); -struct lua_Debug { - int event; - const char *name; - const char *namewhat; - const char *what; - const char *source; - int currentline; - int linedefined; - int lastlinedefined; - unsigned char nups; - unsigned char nparams; - char isvararg; - char istailcall; - char short_src[LUA_IDSIZE]; - struct CallInfo *i_ci; -}; - -SYMBOL_DECLARE(lua_State *, lua_newstate, lua_Alloc f, void *ud) -SYMBOL_DECLARE(void, lua_close, lua_State *L) -SYMBOL_DECLARE(lua_State *, lua_newthread, lua_State *L) -SYMBOL_DECLARE(lua_CFunction, lua_atpanic, lua_State *L, lua_CFunction panicf) -SYMBOL_DECLARE(const lua_Number *, lua_version, lua_State *L) -SYMBOL_DECLARE(int, lua_absindex, lua_State *L, int idx) -SYMBOL_DECLARE(int, lua_gettop, lua_State *L) -SYMBOL_DECLARE(void, lua_settop, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_pushvalue, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_copy, lua_State *L, int fromidx, int toidx) -SYMBOL_DECLARE(int, lua_checkstack, lua_State *L, int sz) -SYMBOL_DECLARE(void, lua_xmove, lua_State *from, lua_State *to, int n) -SYMBOL_DECLARE(int, lua_isnumber, lua_State *L, int idx) -SYMBOL_DECLARE(int, lua_isstring, lua_State *L, int idx) -SYMBOL_DECLARE(int, lua_iscfunction, lua_State *L, int idx) -SYMBOL_DECLARE(int, lua_isuserdata, lua_State *L, int idx) -SYMBOL_DECLARE(int, lua_type, lua_State *L, int idx) -SYMBOL_DECLARE(const char *, lua_typename, lua_State *L, int tp) -SYMBOL_DECLARE(lua_Number, lua_tonumberx, lua_State *L, int idx, int *isnum) -SYMBOL_DECLARE(lua_Integer, lua_tointegerx, lua_State *L, int idx, int *isnum) -SYMBOL_DECLARE(lua_Unsigned, lua_tounsignedx, lua_State *L, int idx, int *isnum) -SYMBOL_DECLARE(int, lua_toboolean, lua_State *L, int idx) -SYMBOL_DECLARE(const char *, lua_tolstring, lua_State *L, int idx, size_t *len) -SYMBOL_DECLARE(size_t, lua_rawlen, lua_State *L, int idx) -SYMBOL_DECLARE(lua_CFunction, lua_tocfunction, lua_State *L, int idx) -SYMBOL_DECLARE(void *, lua_touserdata, lua_State *L, int idx) -SYMBOL_DECLARE(lua_State *, lua_tothread, lua_State *L, int idx) -SYMBOL_DECLARE(const void *, lua_topointer, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_arith, lua_State *L, int op) -SYMBOL_DECLARE(int, lua_rawequal, lua_State *L, int idx1, int idx2) -SYMBOL_DECLARE(int, lua_compare, lua_State *L, int idx1, int idx2, int op) -SYMBOL_DECLARE(void, lua_pushnil, lua_State *L) -SYMBOL_DECLARE(void, lua_pushnumber, lua_State *L, lua_Number n) -SYMBOL_DECLARE(void, lua_pushinteger, lua_State *L, lua_Integer n) -SYMBOL_DECLARE(void, lua_pushunsigned, lua_State *L, lua_Unsigned n) -SYMBOL_DECLARE(const char *, lua_pushlstring, lua_State *L, const char *s, size_t l) -SYMBOL_DECLARE(const char *, lua_pushstring, lua_State *L, const char *s) -SYMBOL_DECLARE(const char *, lua_pushvfstring, lua_State *L, const char *fmt, va_list argp) -SYMBOL_DECLARE(const char *, lua_pushfstring, lua_State *L, const char *fmt, ...) -SYMBOL_DECLARE(void, lua_pushcclosure, lua_State *L, lua_CFunction fn, int n) -SYMBOL_DECLARE(void, lua_pushboolean, lua_State *L, int b) -SYMBOL_DECLARE(void, lua_pushlightuserdata, lua_State *L, void *p) -SYMBOL_DECLARE(int, lua_pushthread, lua_State *L) -SYMBOL_DECLARE(void, lua_getglobal, lua_State *L, const char *var) -SYMBOL_DECLARE(void, lua_gettable, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_getfield, lua_State *L, int idx, const char *k) -SYMBOL_DECLARE(void, lua_rawget, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_rawgeti, lua_State *L, int idx, int n) -SYMBOL_DECLARE(void, lua_rawgetp, lua_State *L, int idx, const void *p) -SYMBOL_DECLARE(void, lua_createtable, lua_State *L, int narr, int nrec) -SYMBOL_DECLARE(void *, lua_newuserdata, lua_State *L, size_t sz) -SYMBOL_DECLARE(void *, lua_newuserdatauv, lua_State *L, size_t sz, int nuvalue) -SYMBOL_DECLARE(int, lua_getmetatable, lua_State *L, int objindex) -SYMBOL_DECLARE(void, lua_getuservalue, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_getiuservalue, lua_State *L, int idx, int n) -SYMBOL_DECLARE(void, lua_setglobal, lua_State *L, const char *var) -SYMBOL_DECLARE(void, lua_settable, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_setfield, lua_State *L, int idx, const char *k) -SYMBOL_DECLARE(void, lua_rawset, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_rawseti, lua_State *L, int idx, int n) -SYMBOL_DECLARE(void, lua_rawsetp, lua_State *L, int idx, const void *p) -SYMBOL_DECLARE(int, lua_setmetatable, lua_State *L, int objindex) -SYMBOL_DECLARE(void, lua_setuservalue, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_setiuservalue, lua_State *L, int idx, int n) -SYMBOL_DECLARE(void, lua_callk, lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k) -SYMBOL_DECLARE(int, lua_getctx, lua_State *L, int *ctx) -SYMBOL_DECLARE(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k) -SYMBOL_DECLARE(int, lua_load, lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode) -SYMBOL_DECLARE(int, lua_dump, lua_State *L, lua_Writer writer, void *data, int strip) -SYMBOL_DECLARE(int, lua_yieldk, lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k) -SYMBOL_DECLARE(int, lua_resume, lua_State *L, lua_State *from, int narg) -SYMBOL_DECLARE(int, lua_status, lua_State *L) -SYMBOL_DECLARE(int, lua_gc, lua_State *L, int what, int data) -SYMBOL_DECLARE(int, lua_error, lua_State *L) -SYMBOL_DECLARE(int, lua_next, lua_State *L, int idx) -SYMBOL_DECLARE(void, lua_concat, lua_State *L, int n) -SYMBOL_DECLARE(void, lua_len, lua_State *L, int idx) -SYMBOL_DECLARE(lua_Alloc, lua_getallocf, lua_State *L, void **ud) -SYMBOL_DECLARE(void, lua_setallocf, lua_State *L, lua_Alloc f, void *ud) -SYMBOL_DECLARE(int, lua_getstack, lua_State *L, int level, lua_Debug *ar) -SYMBOL_DECLARE(int, lua_getinfo, lua_State *L, const char *what, lua_Debug *ar) -SYMBOL_DECLARE(const char *, lua_getlocal, lua_State *L, const lua_Debug *ar, int n) -SYMBOL_DECLARE(const char *, lua_setlocal, lua_State *L, const lua_Debug *ar, int n) -SYMBOL_DECLARE(const char *, lua_getupvalue, lua_State *L, int funcindex, int n) -SYMBOL_DECLARE(const char *, lua_setupvalue, lua_State *L, int funcindex, int n) -SYMBOL_DECLARE(void *, lua_upvalueid, lua_State *L, int fidx, int n) -SYMBOL_DECLARE(void, lua_upvaluejoin, lua_State *L, int fidx1, int n1, int fidx2, int n2) -SYMBOL_DECLARE(int, lua_sethook, lua_State *L, lua_Hook func, int mask, int count) -SYMBOL_DECLARE(lua_Hook, lua_gethook, lua_State *L) -SYMBOL_DECLARE(int, lua_gethookmask, lua_State *L) -SYMBOL_DECLARE(int, lua_gethookcount, lua_State *L) - -#define lua_h -#define LUA_VERSION_MAJOR "5" -#define LUA_VERSION_MINOR "4" -#define LUA_VERSION_NUM 504 -#define LUA_VERSION_RELEASE "4" -#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR -#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2015 Lua.org, PUC-Rio" -#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" -#define LUA_SIGNATURE "\033Lua" -#define LUA_MULTRET (-1) -#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX -#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) -#define LUA_OK 0 -#define LUA_YIELD 1 -#define LUA_ERRRUN 2 -#define LUA_ERRSYNTAX 3 -#define LUA_ERRMEM 4 -#define LUA_ERRGCMM 5 -#define LUA_ERRERR 6 -#define LUA_TNONE (-1) -#define LUA_TNIL 0 -#define LUA_TBOOLEAN 1 -#define LUA_TLIGHTUSERDATA 2 -#define LUA_TNUMBER 3 -#define LUA_TSTRING 4 -#define LUA_TTABLE 5 -#define LUA_TFUNCTION 6 -#define LUA_TUSERDATA 7 -#define LUA_TTHREAD 8 -#define LUA_NUMTAGS 9 -#define LUA_MINSTACK 20 -#define LUA_RIDX_MAINTHREAD 1 -#define LUA_RIDX_GLOBALS 2 -#define LUA_RIDX_LAST LUA_RIDX_GLOBALS -#define LUA_OPADD 0 -#define LUA_OPSUB 1 -#define LUA_OPMUL 2 -#define LUA_OPDIV 3 -#define LUA_OPMOD 4 -#define LUA_OPPOW 5 -#define LUA_OPUNM 6 -#define LUA_OPEQ 0 -#define LUA_OPLT 1 -#define LUA_OPLE 2 -#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) -#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) -#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) -#define LUA_GCSTOP 0 -#define LUA_GCRESTART 1 -#define LUA_GCCOLLECT 2 -#define LUA_GCCOUNT 3 -#define LUA_GCCOUNTB 4 -#define LUA_GCSTEP 5 -#define LUA_GCSETPAUSE 6 -#define LUA_GCSETSTEPMUL 7 -#define LUA_GCSETMAJORINC 8 -#define LUA_GCISRUNNING 9 -#define LUA_GCGEN 10 -#define LUA_GCINC 11 -#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL) -#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL) -#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL) -#define lua_pop(L,n) lua_settop(L, -(n)-1) -#define lua_newtable(L) lua_createtable(L, 0, 0) -#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) -#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) -#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) -#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) -#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) -#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) -#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) -#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) -#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) -#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) -#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) -#define lua_pushglobaltable(L) lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS) -#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) -#define lua_insert(L,idx) lua_rotate(L, (idx), 1) -#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1)) -#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) -#define LUA_HOOKCALL 0 -#define LUA_HOOKRET 1 -#define LUA_HOOKLINE 2 -#define LUA_HOOKCOUNT 3 -#define LUA_HOOKTAILCALL 4 -#define LUA_MASKCALL (1 << LUA_HOOKCALL) -#define LUA_MASKRET (1 << LUA_HOOKRET) -#define LUA_MASKLINE (1 << LUA_HOOKLINE) -#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) - -/** lauxlib.h **/ - -typedef struct luaL_Reg { - const char *name; - lua_CFunction func; -} luaL_Reg; -typedef struct luaL_Buffer { - char *b; - size_t size; - size_t n; - lua_State *L; - char initb[LUAL_BUFFERSIZE]; -} luaL_Buffer; -typedef struct luaL_Stream { - FILE *f; - lua_CFunction closef; -} luaL_Stream; - -SYMBOL_DECLARE(void, luaL_checkversion_, lua_State *L, lua_Number ver) -SYMBOL_DECLARE(int, luaL_getmetafield, lua_State *L, int obj, const char *e) -SYMBOL_DECLARE(int, luaL_callmeta, lua_State *L, int obj, const char *e) -SYMBOL_DECLARE(const char *, luaL_tolstring, lua_State *L, int idx, size_t *len) -SYMBOL_DECLARE(int, luaL_argerror, lua_State *L, int numarg, const char *extramsg) -SYMBOL_DECLARE(const char *, luaL_checklstring, lua_State *L, int numArg, size_t *l) -SYMBOL_DECLARE(const char *, luaL_optlstring, lua_State *L, int numArg, const char *def, size_t *l) -SYMBOL_DECLARE(lua_Number, luaL_checknumber, lua_State *L, int numArg) -SYMBOL_DECLARE(lua_Number, luaL_optnumber, lua_State *L, int nArg, lua_Number def) -SYMBOL_DECLARE(lua_Integer, luaL_checkinteger, lua_State *L, int numArg) -SYMBOL_DECLARE(lua_Integer, luaL_optinteger, lua_State *L, int nArg, lua_Integer def) -SYMBOL_DECLARE(lua_Unsigned, luaL_checkunsigned, lua_State *L, int numArg) -SYMBOL_DECLARE(lua_Unsigned, luaL_optunsigned, lua_State *L, int numArg, lua_Unsigned def) -SYMBOL_DECLARE(void, luaL_checkstack, lua_State *L, int sz, const char *msg) -SYMBOL_DECLARE(void, luaL_checktype, lua_State *L, int narg, int t) -SYMBOL_DECLARE(void, luaL_checkany, lua_State *L, int narg) -SYMBOL_DECLARE(int, luaL_newmetatable, lua_State *L, const char *tname) -SYMBOL_DECLARE(void, luaL_setmetatable, lua_State *L, const char *tname) -SYMBOL_DECLARE(void *, luaL_testudata, lua_State *L, int ud, const char *tname) -SYMBOL_DECLARE(void *, luaL_checkudata, lua_State *L, int ud, const char *tname) -SYMBOL_DECLARE(void, luaL_where, lua_State *L, int lvl) -SYMBOL_DECLARE(int, luaL_error, lua_State *L, const char *fmt, ...) -SYMBOL_DECLARE(int, luaL_checkoption, lua_State *L, int narg, const char *def, const char *const lst[]) -SYMBOL_DECLARE(int, luaL_fileresult, lua_State *L, int stat, const char *fname) -SYMBOL_DECLARE(int, luaL_execresult, lua_State *L, int stat) -SYMBOL_DECLARE(int, luaL_ref, lua_State *L, int t) -SYMBOL_DECLARE(void, luaL_unref, lua_State *L, int t, int ref) -SYMBOL_DECLARE(int, luaL_loadfilex, lua_State *L, const char *filename, const char *mode) -SYMBOL_DECLARE(int, luaL_loadbufferx, lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) -SYMBOL_DECLARE(int, luaL_loadstring, lua_State *L, const char *s) -SYMBOL_DECLARE(lua_State *, luaL_newstate, void) -SYMBOL_DECLARE(int, luaL_len, lua_State *L, int idx) -SYMBOL_DECLARE(const char *, luaL_gsub, lua_State *L, const char *s, const char *p, const char *r) -SYMBOL_DECLARE(void, luaL_setfuncs, lua_State *L, const luaL_Reg *l, int nup) -SYMBOL_DECLARE(int, luaL_getsubtable, lua_State *L, int idx, const char *fname) -SYMBOL_DECLARE(void, luaL_traceback, lua_State *L, lua_State *L1, const char *msg, int level) -SYMBOL_DECLARE(void, luaL_requiref, lua_State *L, const char *modname, lua_CFunction openf, int glb) -SYMBOL_DECLARE(void, luaL_buffinit, lua_State *L, luaL_Buffer *B) -SYMBOL_DECLARE(char *, luaL_prepbuffsize, luaL_Buffer *B, size_t sz) -SYMBOL_DECLARE(void, luaL_addlstring, luaL_Buffer *B, const char *s, size_t l) -SYMBOL_DECLARE(void, luaL_addstring, luaL_Buffer *B, const char *s) -SYMBOL_DECLARE(void, luaL_addvalue, luaL_Buffer *B) -SYMBOL_DECLARE(void, luaL_pushresult, luaL_Buffer *B) -SYMBOL_DECLARE(void, luaL_pushresultsize, luaL_Buffer *B, size_t sz) -SYMBOL_DECLARE(char *, luaL_buffinitsize, lua_State *L, luaL_Buffer *B, size_t sz) -SYMBOL_DECLARE(void, luaL_openlibs, lua_State *L) - -#define lauxlib_h -#define LUA_ERRFILE (LUA_ERRERR+1) -#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) -#define LUA_NOREF (-2) -#define LUA_REFNIL (-1) -#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) -#define luaL_newlibtable(L,l) lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) -#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) -#define luaL_argcheck(L, cond,numarg,extramsg) ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) -#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) -#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) -#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) -#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) -#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) -#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) -#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) -#define luaL_dofile(L, fn) (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) -#define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) -#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) -#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) -#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) -#define luaL_addchar(B,c) ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), ((B)->b[(B)->n++] = (c))) -#define luaL_addsize(B,s) ((B)->n += (s)) -#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) -#define LUA_FILEHANDLE "FILE*" - -#ifdef LITE_XL_PLUGIN_ENTRYPOINT - -SYMBOL_WRAP_DECL(lua_State *, lua_newstate, lua_Alloc f, void *ud){ - SYMBOL_WRAP_CALL(lua_newstate, f, ud); -} -SYMBOL_WRAP_DECL(void, lua_close, lua_State *L){ - SYMBOL_WRAP_CALL(lua_close, L); -} -SYMBOL_WRAP_DECL(lua_State *, lua_newthread, lua_State *L){ - SYMBOL_WRAP_CALL(lua_newthread, L); -} -SYMBOL_WRAP_DECL(lua_CFunction, lua_atpanic, lua_State *L, lua_CFunction panicf){ - SYMBOL_WRAP_CALL(lua_atpanic, L, panicf); -} -SYMBOL_WRAP_DECL(const lua_Number *, lua_version, lua_State *L){ - SYMBOL_WRAP_CALL(lua_version, L); -} -SYMBOL_WRAP_DECL(int, lua_absindex, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_absindex, L, idx); -} -SYMBOL_WRAP_DECL(int, lua_gettop, lua_State *L){ - SYMBOL_WRAP_CALL(lua_gettop, L); -} -SYMBOL_WRAP_DECL(void, lua_settop, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_settop, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_pushvalue, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_pushvalue, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_copy, lua_State *L, int fromidx, int toidx){ - SYMBOL_WRAP_CALL(lua_copy, L, fromidx, toidx); -} -SYMBOL_WRAP_DECL(int, lua_checkstack, lua_State *L, int sz){ - SYMBOL_WRAP_CALL(lua_checkstack, L, sz); -} -SYMBOL_WRAP_DECL(void, lua_xmove, lua_State *from, lua_State *to, int n){ - SYMBOL_WRAP_CALL(lua_xmove, from, to, n); -} -SYMBOL_WRAP_DECL(int, lua_isnumber, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_isnumber, L, idx); -} -SYMBOL_WRAP_DECL(int, lua_isstring, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_isstring, L, idx); -} -SYMBOL_WRAP_DECL(int, lua_iscfunction, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_iscfunction, L, idx); -} -SYMBOL_WRAP_DECL(int, lua_isuserdata, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_isuserdata, L, idx); -} -SYMBOL_WRAP_DECL(int, lua_type, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_type, L, idx); -} -SYMBOL_WRAP_DECL(const char *, lua_typename, lua_State *L, int tp){ - SYMBOL_WRAP_CALL(lua_typename, L, tp); -} -SYMBOL_WRAP_DECL(lua_Number, lua_tonumberx, lua_State *L, int idx, int *isnum){ - SYMBOL_WRAP_CALL(lua_tonumberx, L, idx, isnum); -} -SYMBOL_WRAP_DECL(lua_Integer, lua_tointegerx, lua_State *L, int idx, int *isnum){ - SYMBOL_WRAP_CALL(lua_tointegerx, L, idx, isnum); -} -SYMBOL_WRAP_DECL(lua_Unsigned, lua_tounsignedx, lua_State *L, int idx, int *isnum){ - SYMBOL_WRAP_CALL(lua_tounsignedx, L, idx, isnum); -} -SYMBOL_WRAP_DECL(int, lua_toboolean, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_toboolean, L, idx); -} -SYMBOL_WRAP_DECL(const char *, lua_tolstring, lua_State *L, int idx, size_t *len){ - SYMBOL_WRAP_CALL(lua_tolstring, L, idx, len); -} -SYMBOL_WRAP_DECL(size_t, lua_rawlen, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_rawlen, L, idx); -} -SYMBOL_WRAP_DECL(lua_CFunction, lua_tocfunction, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_tocfunction, L, idx); -} -SYMBOL_WRAP_DECL(void *, lua_touserdata, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_touserdata, L, idx); -} -SYMBOL_WRAP_DECL(lua_State *, lua_tothread, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_tothread, L, idx); -} -SYMBOL_WRAP_DECL(const void *, lua_topointer, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_topointer, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_arith, lua_State *L, int op){ - SYMBOL_WRAP_CALL(lua_arith, L, op); -} -SYMBOL_WRAP_DECL(int, lua_rawequal, lua_State *L, int idx1, int idx2){ - SYMBOL_WRAP_CALL(lua_rawequal, L, idx1, idx2); -} -SYMBOL_WRAP_DECL(int, lua_compare, lua_State *L, int idx1, int idx2, int op){ - SYMBOL_WRAP_CALL(lua_compare, L, idx1, idx2, op); -} -SYMBOL_WRAP_DECL(void, lua_pushnil, lua_State *L){ - SYMBOL_WRAP_CALL(lua_pushnil, L); -} -SYMBOL_WRAP_DECL(void, lua_pushnumber, lua_State *L, lua_Number n){ - SYMBOL_WRAP_CALL(lua_pushnumber, L, n); -} -SYMBOL_WRAP_DECL(void, lua_pushinteger, lua_State *L, lua_Integer n){ - SYMBOL_WRAP_CALL(lua_pushinteger, L, n); -} -SYMBOL_WRAP_DECL(void, lua_pushunsigned, lua_State *L, lua_Unsigned n){ - SYMBOL_WRAP_CALL(lua_pushunsigned, L, n); -} -SYMBOL_WRAP_DECL(const char *, lua_pushlstring, lua_State *L, const char *s, size_t l){ - SYMBOL_WRAP_CALL(lua_pushlstring, L, s, l); -} -SYMBOL_WRAP_DECL(const char *, lua_pushstring, lua_State *L, const char *s){ - SYMBOL_WRAP_CALL(lua_pushstring, L, s); -} -SYMBOL_WRAP_DECL(const char *, lua_pushvfstring, lua_State *L, const char *fmt, va_list argp){ - SYMBOL_WRAP_CALL(lua_pushvfstring, L, fmt, argp); -} -SYMBOL_WRAP_DECL(const char *, lua_pushfstring, lua_State *L, const char *fmt, ...){ - SYMBOL_WRAP_CALL(lua_pushfstring, L, fmt); -} -SYMBOL_WRAP_DECL(void, lua_pushcclosure, lua_State *L, lua_CFunction fn, int n){ - SYMBOL_WRAP_CALL(lua_pushcclosure, L, fn, n); -} -SYMBOL_WRAP_DECL(void, lua_pushboolean, lua_State *L, int b){ - SYMBOL_WRAP_CALL(lua_pushboolean, L, b); -} -SYMBOL_WRAP_DECL(void, lua_pushlightuserdata, lua_State *L, void *p){ - SYMBOL_WRAP_CALL(lua_pushlightuserdata, L, p); -} -SYMBOL_WRAP_DECL(int, lua_pushthread, lua_State *L){ - SYMBOL_WRAP_CALL(lua_pushthread, L); -} -SYMBOL_WRAP_DECL(void, lua_getglobal, lua_State *L, const char *var){ - SYMBOL_WRAP_CALL(lua_getglobal, L, var); -} -SYMBOL_WRAP_DECL(void, lua_gettable, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_gettable, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_getfield, lua_State *L, int idx, const char *k){ - SYMBOL_WRAP_CALL(lua_getfield, L, idx, k); -} -SYMBOL_WRAP_DECL(void, lua_rawget, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_rawget, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_rawgeti, lua_State *L, int idx, int n){ - SYMBOL_WRAP_CALL(lua_rawgeti, L, idx, n); -} -SYMBOL_WRAP_DECL(void, lua_rawgetp, lua_State *L, int idx, const void *p){ - SYMBOL_WRAP_CALL(lua_rawgetp, L, idx, p); -} -SYMBOL_WRAP_DECL(void, lua_createtable, lua_State *L, int narr, int nrec){ - SYMBOL_WRAP_CALL(lua_createtable, L, narr, nrec); -} -SYMBOL_WRAP_DECL(void *, lua_newuserdata, lua_State *L, size_t sz){ - if (__lua_newuserdatauv != NULL) { - return lua_newuserdatauv(L, sz, 1); - } else if (__lua_newuserdata != NULL) { - SYMBOL_WRAP_CALL(lua_newuserdata, L, sz); - } - SYMBOL_WRAP_CALL_FB(lua_newuserdata, L, sz); -} -SYMBOL_WRAP_DECL(void *, lua_newuserdatauv, lua_State *L, size_t sz, int nuvalue){ - SYMBOL_WRAP_CALL(lua_newuserdatauv, L, sz, nuvalue); -} -SYMBOL_WRAP_DECL(int, lua_getmetatable, lua_State *L, int objindex){ - SYMBOL_WRAP_CALL(lua_getmetatable, L, objindex); -} -SYMBOL_WRAP_DECL(void, lua_getuservalue, lua_State *L, int idx){ - if (__lua_getiuservalue != NULL) { - return lua_getiuservalue(L, idx, 1); - } else if (__lua_getuservalue != NULL) { - SYMBOL_WRAP_CALL(lua_getuservalue, L, idx); - } - SYMBOL_WRAP_CALL_FB(lua_getuservalue, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_getiuservalue, lua_State *L, int idx, int n){ - SYMBOL_WRAP_CALL(lua_getiuservalue, L, idx, n); -} -SYMBOL_WRAP_DECL(void, lua_setglobal, lua_State *L, const char *var){ - SYMBOL_WRAP_CALL(lua_setglobal, L, var); -} -SYMBOL_WRAP_DECL(void, lua_settable, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_settable, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_setfield, lua_State *L, int idx, const char *k){ - SYMBOL_WRAP_CALL(lua_setfield, L, idx, k); -} -SYMBOL_WRAP_DECL(void, lua_rawset, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_rawset, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_rawseti, lua_State *L, int idx, int n){ - SYMBOL_WRAP_CALL(lua_rawseti, L, idx, n); -} -SYMBOL_WRAP_DECL(void, lua_rawsetp, lua_State *L, int idx, const void *p){ - SYMBOL_WRAP_CALL(lua_rawsetp, L, idx, p); -} -SYMBOL_WRAP_DECL(int, lua_setmetatable, lua_State *L, int objindex){ - SYMBOL_WRAP_CALL(lua_setmetatable, L, objindex); -} -SYMBOL_WRAP_DECL(void, lua_setuservalue, lua_State *L, int idx){ - if (__lua_setiuservalue != NULL) { - return lua_setiuservalue(L, idx, 1); - } else if (__lua_setuservalue != NULL) { - SYMBOL_WRAP_CALL(lua_setuservalue, L, idx); - } - SYMBOL_WRAP_CALL_FB(lua_setuservalue, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_setiuservalue, lua_State *L, int idx, int n){ - SYMBOL_WRAP_CALL(lua_setiuservalue, L, idx, n); -} -SYMBOL_WRAP_DECL(void, lua_callk, lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k){ - SYMBOL_WRAP_CALL(lua_callk, L, nargs, nresults, ctx, k); -} -SYMBOL_WRAP_DECL(int, lua_getctx, lua_State *L, int *ctx){ - SYMBOL_WRAP_CALL(lua_getctx, L, ctx); -} -SYMBOL_WRAP_DECL(int, lua_pcallk, lua_State *L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k){ - SYMBOL_WRAP_CALL(lua_pcallk, L, nargs, nresults, errfunc, ctx, k); -} -SYMBOL_WRAP_DECL(int, lua_load, lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode){ - SYMBOL_WRAP_CALL(lua_load, L, reader, dt, chunkname, mode); -} -SYMBOL_WRAP_DECL(int, lua_dump, lua_State *L, lua_Writer writer, void *data, int strip){ - SYMBOL_WRAP_CALL(lua_dump, L, writer, data, strip); -} -SYMBOL_WRAP_DECL(int, lua_yieldk, lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k){ - SYMBOL_WRAP_CALL(lua_yieldk, L, nresults, ctx, k); -} -SYMBOL_WRAP_DECL(int, lua_resume, lua_State *L, lua_State *from, int narg){ - SYMBOL_WRAP_CALL(lua_resume, L, from, narg); -} -SYMBOL_WRAP_DECL(int, lua_status, lua_State *L){ - SYMBOL_WRAP_CALL(lua_status, L); -} -SYMBOL_WRAP_DECL(int, lua_gc, lua_State *L, int what, int data){ - SYMBOL_WRAP_CALL(lua_gc, L, what, data); -} -SYMBOL_WRAP_DECL(int, lua_error, lua_State *L){ - SYMBOL_WRAP_CALL(lua_error, L); -} -SYMBOL_WRAP_DECL(int, lua_next, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_next, L, idx); -} -SYMBOL_WRAP_DECL(void, lua_concat, lua_State *L, int n){ - SYMBOL_WRAP_CALL(lua_concat, L, n); -} -SYMBOL_WRAP_DECL(void, lua_len, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(lua_len, L, idx); -} -SYMBOL_WRAP_DECL(lua_Alloc, lua_getallocf, lua_State *L, void **ud){ - SYMBOL_WRAP_CALL(lua_getallocf, L, ud); -} -SYMBOL_WRAP_DECL(void, lua_setallocf, lua_State *L, lua_Alloc f, void *ud){ - SYMBOL_WRAP_CALL(lua_setallocf, L, f, ud); -} -SYMBOL_WRAP_DECL(int, lua_getstack, lua_State *L, int level, lua_Debug *ar){ - SYMBOL_WRAP_CALL(lua_getstack, L, level, ar); -} -SYMBOL_WRAP_DECL(int, lua_getinfo, lua_State *L, const char *what, lua_Debug *ar){ - SYMBOL_WRAP_CALL(lua_getinfo, L, what, ar); -} -SYMBOL_WRAP_DECL(const char *, lua_getlocal, lua_State *L, const lua_Debug *ar, int n){ - SYMBOL_WRAP_CALL(lua_getlocal, L, ar, n); -} -SYMBOL_WRAP_DECL(const char *, lua_setlocal, lua_State *L, const lua_Debug *ar, int n){ - SYMBOL_WRAP_CALL(lua_setlocal, L, ar, n); -} -SYMBOL_WRAP_DECL(const char *, lua_getupvalue, lua_State *L, int funcindex, int n){ - SYMBOL_WRAP_CALL(lua_getupvalue, L, funcindex, n); -} -SYMBOL_WRAP_DECL(const char *, lua_setupvalue, lua_State *L, int funcindex, int n){ - SYMBOL_WRAP_CALL(lua_setupvalue, L, funcindex, n); -} -SYMBOL_WRAP_DECL(void *, lua_upvalueid, lua_State *L, int fidx, int n){ - SYMBOL_WRAP_CALL(lua_upvalueid, L, fidx, n); -} -SYMBOL_WRAP_DECL(void, lua_upvaluejoin, lua_State *L, int fidx1, int n1, int fidx2, int n2){ - SYMBOL_WRAP_CALL(lua_upvaluejoin, L, fidx1, n1, fidx2, n2); -} -SYMBOL_WRAP_DECL(int, lua_sethook, lua_State *L, lua_Hook func, int mask, int count){ - SYMBOL_WRAP_CALL(lua_sethook, L, func, mask, count); -} -SYMBOL_WRAP_DECL(lua_Hook, lua_gethook, lua_State *L){ - SYMBOL_WRAP_CALL(lua_gethook, L); -} -SYMBOL_WRAP_DECL(int, lua_gethookmask, lua_State *L){ - SYMBOL_WRAP_CALL(lua_gethookmask, L); -} -SYMBOL_WRAP_DECL(int, lua_gethookcount, lua_State *L){ - SYMBOL_WRAP_CALL(lua_gethookcount, L); -} -SYMBOL_WRAP_DECL(void, luaL_checkversion_, lua_State *L, lua_Number ver){ - SYMBOL_WRAP_CALL(luaL_checkversion_, L, ver); -} -SYMBOL_WRAP_DECL(int, luaL_getmetafield, lua_State *L, int obj, const char *e){ - SYMBOL_WRAP_CALL(luaL_getmetafield, L, obj, e); -} -SYMBOL_WRAP_DECL(int, luaL_callmeta, lua_State *L, int obj, const char *e){ - SYMBOL_WRAP_CALL(luaL_callmeta, L, obj, e); -} -SYMBOL_WRAP_DECL(const char *, luaL_tolstring, lua_State *L, int idx, size_t *len){ - SYMBOL_WRAP_CALL(luaL_tolstring, L, idx, len); -} -SYMBOL_WRAP_DECL(int, luaL_argerror, lua_State *L, int numarg, const char *extramsg){ - SYMBOL_WRAP_CALL(luaL_argerror, L, numarg, extramsg); -} -SYMBOL_WRAP_DECL(const char *, luaL_checklstring, lua_State *L, int numArg, size_t *l){ - SYMBOL_WRAP_CALL(luaL_checklstring, L, numArg, l); -} -SYMBOL_WRAP_DECL(const char *, luaL_optlstring, lua_State *L, int numArg, const char *def, size_t *l){ - SYMBOL_WRAP_CALL(luaL_optlstring, L, numArg, def, l); -} -SYMBOL_WRAP_DECL(lua_Number, luaL_checknumber, lua_State *L, int numArg){ - SYMBOL_WRAP_CALL(luaL_checknumber, L, numArg); -} -SYMBOL_WRAP_DECL(lua_Number, luaL_optnumber, lua_State *L, int nArg, lua_Number def){ - SYMBOL_WRAP_CALL(luaL_optnumber, L, nArg, def); -} -SYMBOL_WRAP_DECL(lua_Integer, luaL_checkinteger, lua_State *L, int numArg){ - SYMBOL_WRAP_CALL(luaL_checkinteger, L, numArg); -} -SYMBOL_WRAP_DECL(lua_Integer, luaL_optinteger, lua_State *L, int nArg, lua_Integer def){ - SYMBOL_WRAP_CALL(luaL_optinteger, L, nArg, def); -} -SYMBOL_WRAP_DECL(lua_Unsigned, luaL_checkunsigned, lua_State *L, int numArg){ - SYMBOL_WRAP_CALL(luaL_checkunsigned, L, numArg); -} -SYMBOL_WRAP_DECL(lua_Unsigned, luaL_optunsigned, lua_State *L, int numArg, lua_Unsigned def){ - SYMBOL_WRAP_CALL(luaL_optunsigned, L, numArg, def); -} -SYMBOL_WRAP_DECL(void, luaL_checkstack, lua_State *L, int sz, const char *msg){ - SYMBOL_WRAP_CALL(luaL_checkstack, L, sz, msg); -} -SYMBOL_WRAP_DECL(void, luaL_checktype, lua_State *L, int narg, int t){ - SYMBOL_WRAP_CALL(luaL_checktype, L, narg, t); -} -SYMBOL_WRAP_DECL(void, luaL_checkany, lua_State *L, int narg){ - SYMBOL_WRAP_CALL(luaL_checkany, L, narg); -} -SYMBOL_WRAP_DECL(int, luaL_newmetatable, lua_State *L, const char *tname){ - SYMBOL_WRAP_CALL(luaL_newmetatable, L, tname); -} -SYMBOL_WRAP_DECL(void, luaL_setmetatable, lua_State *L, const char *tname){ - SYMBOL_WRAP_CALL(luaL_setmetatable, L, tname); -} -SYMBOL_WRAP_DECL(void *, luaL_testudata, lua_State *L, int ud, const char *tname){ - SYMBOL_WRAP_CALL(luaL_testudata, L, ud, tname); -} -SYMBOL_WRAP_DECL(void *, luaL_checkudata, lua_State *L, int ud, const char *tname){ - SYMBOL_WRAP_CALL(luaL_checkudata, L, ud, tname); -} -SYMBOL_WRAP_DECL(void, luaL_where, lua_State *L, int lvl){ - SYMBOL_WRAP_CALL(luaL_where, L, lvl); -} -SYMBOL_WRAP_DECL(int, luaL_error, lua_State *L, const char *fmt, ...){ - va_list argp; - va_start(argp, fmt); - luaL_where(L, 1); - lua_pushvfstring(L, fmt, argp); - va_end(argp); - lua_concat(L, 2); - return lua_error(L); -} -SYMBOL_WRAP_DECL(int, luaL_checkoption, lua_State *L, int narg, const char *def, const char *const lst[]){ - SYMBOL_WRAP_CALL(luaL_checkoption, L, narg, def, lst); -} -SYMBOL_WRAP_DECL(int, luaL_fileresult, lua_State *L, int stat, const char *fname){ - SYMBOL_WRAP_CALL(luaL_fileresult, L, stat, fname); -} -SYMBOL_WRAP_DECL(int, luaL_execresult, lua_State *L, int stat){ - SYMBOL_WRAP_CALL(luaL_execresult, L, stat); -} -SYMBOL_WRAP_DECL(int, luaL_ref, lua_State *L, int t){ - SYMBOL_WRAP_CALL(luaL_ref, L, t); -} -SYMBOL_WRAP_DECL(void, luaL_unref, lua_State *L, int t, int ref){ - SYMBOL_WRAP_CALL(luaL_unref, L, t, ref); -} -SYMBOL_WRAP_DECL(int, luaL_loadfilex, lua_State *L, const char *filename, const char *mode){ - SYMBOL_WRAP_CALL(luaL_loadfilex, L, filename, mode); -} -SYMBOL_WRAP_DECL(int, luaL_loadbufferx, lua_State *L, const char *buff, size_t sz, const char *name, const char *mode){ - SYMBOL_WRAP_CALL(luaL_loadbufferx, L, buff, sz, name, mode); -} -SYMBOL_WRAP_DECL(int, luaL_loadstring, lua_State *L, const char *s){ - SYMBOL_WRAP_CALL(luaL_loadstring, L, s); -} -SYMBOL_WRAP_DECL(lua_State *, luaL_newstate, void){ - return __luaL_newstate(); -} -SYMBOL_WRAP_DECL(int, luaL_len, lua_State *L, int idx){ - SYMBOL_WRAP_CALL(luaL_len, L, idx); -} -SYMBOL_WRAP_DECL(const char *, luaL_gsub, lua_State *L, const char *s, const char *p, const char *r){ - SYMBOL_WRAP_CALL(luaL_gsub, L, s, p, r); -} -SYMBOL_WRAP_DECL(void, luaL_setfuncs, lua_State *L, const luaL_Reg *l, int nup){ - SYMBOL_WRAP_CALL(luaL_setfuncs, L, l, nup); -} -SYMBOL_WRAP_DECL(int, luaL_getsubtable, lua_State *L, int idx, const char *fname){ - SYMBOL_WRAP_CALL(luaL_getsubtable, L, idx, fname); -} -SYMBOL_WRAP_DECL(void, luaL_traceback, lua_State *L, lua_State *L1, const char *msg, int level){ - SYMBOL_WRAP_CALL(luaL_traceback, L, L1, msg, level); -} -SYMBOL_WRAP_DECL(void, luaL_requiref, lua_State *L, const char *modname, lua_CFunction openf, int glb){ - SYMBOL_WRAP_CALL(luaL_requiref, L, modname, openf, glb); -} -SYMBOL_WRAP_DECL(void, luaL_buffinit, lua_State *L, luaL_Buffer *B){ - SYMBOL_WRAP_CALL(luaL_buffinit, L, B); -} -SYMBOL_WRAP_DECL(char *, luaL_prepbuffsize, luaL_Buffer *B, size_t sz){ - SYMBOL_WRAP_CALL(luaL_prepbuffsize, B, sz); -} -SYMBOL_WRAP_DECL(void, luaL_addlstring, luaL_Buffer *B, const char *s, size_t l){ - SYMBOL_WRAP_CALL(luaL_addlstring, B, s, l); -} -SYMBOL_WRAP_DECL(void, luaL_addstring, luaL_Buffer *B, const char *s){ - SYMBOL_WRAP_CALL(luaL_addstring, B, s); -} -SYMBOL_WRAP_DECL(void, luaL_addvalue, luaL_Buffer *B){ - SYMBOL_WRAP_CALL(luaL_addvalue, B); -} -SYMBOL_WRAP_DECL(void, luaL_pushresult, luaL_Buffer *B){ - SYMBOL_WRAP_CALL(luaL_pushresult, B); -} -SYMBOL_WRAP_DECL(void, luaL_pushresultsize, luaL_Buffer *B, size_t sz){ - SYMBOL_WRAP_CALL(luaL_pushresultsize, B, sz); -} -SYMBOL_WRAP_DECL(char *, luaL_buffinitsize, lua_State *L, luaL_Buffer *B, size_t sz){ - SYMBOL_WRAP_CALL(luaL_buffinitsize, L, B, sz); -} -SYMBOL_WRAP_DECL(void, luaL_openlibs, lua_State *L){ - SYMBOL_WRAP_CALL(luaL_openlibs, L); -} - -#define IMPORT_SYMBOL(name, ret, ...) \ - __##name = (\ - __##name = (ret (*) (__VA_ARGS__)) symbol(#name), \ - __##name == NULL ? &__lite_xl_fallback_##name : __##name\ - ) - -#define IMPORT_SYMBOL_OPT(name, ret, ...) \ - __##name = symbol(#name) - -static void lite_xl_plugin_init(void *XL) { - void* (*symbol)(const char *) = (void* (*) (const char *)) XL; - IMPORT_SYMBOL(lua_newstate, lua_State *, lua_Alloc f, void *ud); - IMPORT_SYMBOL(lua_close, void , lua_State *L); - IMPORT_SYMBOL(lua_newthread, lua_State *, lua_State *L); - IMPORT_SYMBOL(lua_atpanic, lua_CFunction , lua_State *L, lua_CFunction panicf); - IMPORT_SYMBOL(lua_version, const lua_Number *, lua_State *L); - IMPORT_SYMBOL(lua_absindex, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_gettop, int , lua_State *L); - IMPORT_SYMBOL(lua_settop, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_pushvalue, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_copy, void , lua_State *L, int fromidx, int toidx); - IMPORT_SYMBOL(lua_checkstack, int , lua_State *L, int sz); - IMPORT_SYMBOL(lua_xmove, void , lua_State *from, lua_State *to, int n); - IMPORT_SYMBOL(lua_isnumber, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_isstring, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_iscfunction, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_isuserdata, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_type, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_typename, const char *, lua_State *L, int tp); - IMPORT_SYMBOL(lua_tonumberx, lua_Number , lua_State *L, int idx, int *isnum); - IMPORT_SYMBOL(lua_tointegerx, lua_Integer , lua_State *L, int idx, int *isnum); - IMPORT_SYMBOL(lua_tounsignedx, lua_Unsigned , lua_State *L, int idx, int *isnum); - IMPORT_SYMBOL(lua_toboolean, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_tolstring, const char *, lua_State *L, int idx, size_t *len); - IMPORT_SYMBOL(lua_rawlen, size_t , lua_State *L, int idx); - IMPORT_SYMBOL(lua_tocfunction, lua_CFunction , lua_State *L, int idx); - IMPORT_SYMBOL(lua_touserdata, void *, lua_State *L, int idx); - IMPORT_SYMBOL(lua_tothread, lua_State *, lua_State *L, int idx); - IMPORT_SYMBOL(lua_topointer, const void *, lua_State *L, int idx); - IMPORT_SYMBOL(lua_arith, void , lua_State *L, int op); - IMPORT_SYMBOL(lua_rawequal, int , lua_State *L, int idx1, int idx2); - IMPORT_SYMBOL(lua_compare, int , lua_State *L, int idx1, int idx2, int op); - IMPORT_SYMBOL(lua_pushnil, void , lua_State *L); - IMPORT_SYMBOL(lua_pushnumber, void , lua_State *L, lua_Number n); - IMPORT_SYMBOL(lua_pushinteger, void , lua_State *L, lua_Integer n); - IMPORT_SYMBOL(lua_pushunsigned, void , lua_State *L, lua_Unsigned n); - IMPORT_SYMBOL(lua_pushlstring, const char *, lua_State *L, const char *s, size_t l); - IMPORT_SYMBOL(lua_pushstring, const char *, lua_State *L, const char *s); - IMPORT_SYMBOL(lua_pushvfstring, const char *, lua_State *L, const char *fmt, va_list argp); - IMPORT_SYMBOL(lua_pushfstring, const char *, lua_State *L, const char *fmt, ...); - IMPORT_SYMBOL(lua_pushcclosure, void , lua_State *L, lua_CFunction fn, int n); - IMPORT_SYMBOL(lua_pushboolean, void , lua_State *L, int b); - IMPORT_SYMBOL(lua_pushlightuserdata, void , lua_State *L, void *p); - IMPORT_SYMBOL(lua_pushthread, int , lua_State *L); - IMPORT_SYMBOL(lua_getglobal, void , lua_State *L, const char *var); - IMPORT_SYMBOL(lua_gettable, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_getfield, void , lua_State *L, int idx, const char *k); - IMPORT_SYMBOL(lua_rawget, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_rawgeti, void , lua_State *L, int idx, int n); - IMPORT_SYMBOL(lua_rawgetp, void , lua_State *L, int idx, const void *p); - IMPORT_SYMBOL(lua_createtable, void , lua_State *L, int narr, int nrec); - IMPORT_SYMBOL_OPT(lua_newuserdata, void *, lua_State *L, size_t sz); - IMPORT_SYMBOL(lua_newuserdatauv, void *, lua_State *L, size_t sz, int nuvalue); - IMPORT_SYMBOL(lua_getmetatable, int , lua_State *L, int objindex); - IMPORT_SYMBOL_OPT(lua_getuservalue, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_getiuservalue, void , lua_State *L, int idx, int n); - IMPORT_SYMBOL(lua_setglobal, void , lua_State *L, const char *var); - IMPORT_SYMBOL(lua_settable, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_setfield, void , lua_State *L, int idx, const char *k); - IMPORT_SYMBOL(lua_rawset, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_rawseti, void , lua_State *L, int idx, int n); - IMPORT_SYMBOL(lua_rawsetp, void , lua_State *L, int idx, const void *p); - IMPORT_SYMBOL(lua_setmetatable, int , lua_State *L, int objindex); - IMPORT_SYMBOL_OPT(lua_setuservalue, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_setiuservalue, void , lua_State *L, int idx, int n); - IMPORT_SYMBOL(lua_callk, void , lua_State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k); - IMPORT_SYMBOL(lua_getctx, int , lua_State *L, int *ctx); - IMPORT_SYMBOL(lua_pcallk, int , lua_State *L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k); - IMPORT_SYMBOL(lua_load, int , lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); - IMPORT_SYMBOL(lua_dump, int , lua_State *L, lua_Writer writer, void *data, int strip); - IMPORT_SYMBOL(lua_yieldk, int , lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k); - IMPORT_SYMBOL(lua_resume, int , lua_State *L, lua_State *from, int narg); - IMPORT_SYMBOL(lua_status, int , lua_State *L); - IMPORT_SYMBOL(lua_gc, int , lua_State *L, int what, int data); - IMPORT_SYMBOL(lua_error, int , lua_State *L); - IMPORT_SYMBOL(lua_next, int , lua_State *L, int idx); - IMPORT_SYMBOL(lua_concat, void , lua_State *L, int n); - IMPORT_SYMBOL(lua_len, void , lua_State *L, int idx); - IMPORT_SYMBOL(lua_getallocf, lua_Alloc , lua_State *L, void **ud); - IMPORT_SYMBOL(lua_setallocf, void , lua_State *L, lua_Alloc f, void *ud); - IMPORT_SYMBOL(lua_getstack, int , lua_State *L, int level, lua_Debug *ar); - IMPORT_SYMBOL(lua_getinfo, int , lua_State *L, const char *what, lua_Debug *ar); - IMPORT_SYMBOL(lua_getlocal, const char *, lua_State *L, const lua_Debug *ar, int n); - IMPORT_SYMBOL(lua_setlocal, const char *, lua_State *L, const lua_Debug *ar, int n); - IMPORT_SYMBOL(lua_getupvalue, const char *, lua_State *L, int funcindex, int n); - IMPORT_SYMBOL(lua_setupvalue, const char *, lua_State *L, int funcindex, int n); - IMPORT_SYMBOL(lua_upvalueid, void *, lua_State *L, int fidx, int n); - IMPORT_SYMBOL(lua_upvaluejoin, void , lua_State *L, int fidx1, int n1, int fidx2, int n2); - IMPORT_SYMBOL(lua_sethook, int , lua_State *L, lua_Hook func, int mask, int count); - IMPORT_SYMBOL(lua_gethook, lua_Hook , lua_State *L); - IMPORT_SYMBOL(lua_gethookmask, int , lua_State *L); - IMPORT_SYMBOL(lua_gethookcount, int , lua_State *L); - IMPORT_SYMBOL(luaL_checkversion_, void , lua_State *L, lua_Number ver); - IMPORT_SYMBOL(luaL_getmetafield, int , lua_State *L, int obj, const char *e); - IMPORT_SYMBOL(luaL_callmeta, int , lua_State *L, int obj, const char *e); - IMPORT_SYMBOL(luaL_tolstring, const char *, lua_State *L, int idx, size_t *len); - IMPORT_SYMBOL(luaL_argerror, int , lua_State *L, int numarg, const char *extramsg); - IMPORT_SYMBOL(luaL_checklstring, const char *, lua_State *L, int numArg, size_t *l); - IMPORT_SYMBOL(luaL_optlstring, const char *, lua_State *L, int numArg, const char *def, size_t *l); - IMPORT_SYMBOL(luaL_checknumber, lua_Number , lua_State *L, int numArg); - IMPORT_SYMBOL(luaL_optnumber, lua_Number , lua_State *L, int nArg, lua_Number def); - IMPORT_SYMBOL(luaL_checkinteger, lua_Integer , lua_State *L, int numArg); - IMPORT_SYMBOL(luaL_optinteger, lua_Integer , lua_State *L, int nArg, lua_Integer def); - IMPORT_SYMBOL(luaL_checkunsigned, lua_Unsigned , lua_State *L, int numArg); - IMPORT_SYMBOL(luaL_optunsigned, lua_Unsigned , lua_State *L, int numArg, lua_Unsigned def); - IMPORT_SYMBOL(luaL_checkstack, void , lua_State *L, int sz, const char *msg); - IMPORT_SYMBOL(luaL_checktype, void , lua_State *L, int narg, int t); - IMPORT_SYMBOL(luaL_checkany, void , lua_State *L, int narg); - IMPORT_SYMBOL(luaL_newmetatable, int , lua_State *L, const char *tname); - IMPORT_SYMBOL(luaL_setmetatable, void , lua_State *L, const char *tname); - IMPORT_SYMBOL(luaL_testudata, void *, lua_State *L, int ud, const char *tname); - IMPORT_SYMBOL(luaL_checkudata, void *, lua_State *L, int ud, const char *tname); - IMPORT_SYMBOL(luaL_where, void , lua_State *L, int lvl); - IMPORT_SYMBOL(luaL_error, int , lua_State *L, const char *fmt, ...); - IMPORT_SYMBOL(luaL_checkoption, int , lua_State *L, int narg, const char *def, const char *const lst[]); - IMPORT_SYMBOL(luaL_fileresult, int , lua_State *L, int stat, const char *fname); - IMPORT_SYMBOL(luaL_execresult, int , lua_State *L, int stat); - IMPORT_SYMBOL(luaL_ref, int , lua_State *L, int t); - IMPORT_SYMBOL(luaL_unref, void , lua_State *L, int t, int ref); - IMPORT_SYMBOL(luaL_loadfilex, int , lua_State *L, const char *filename, const char *mode); - IMPORT_SYMBOL(luaL_loadbufferx, int , lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); - IMPORT_SYMBOL(luaL_loadstring, int , lua_State *L, const char *s); - IMPORT_SYMBOL(luaL_newstate, lua_State *, void); - IMPORT_SYMBOL(luaL_len, int , lua_State *L, int idx); - IMPORT_SYMBOL(luaL_gsub, const char *, lua_State *L, const char *s, const char *p, const char *r); - IMPORT_SYMBOL(luaL_setfuncs, void , lua_State *L, const luaL_Reg *l, int nup); - IMPORT_SYMBOL(luaL_getsubtable, int , lua_State *L, int idx, const char *fname); - IMPORT_SYMBOL(luaL_traceback, void , lua_State *L, lua_State *L1, const char *msg, int level); - IMPORT_SYMBOL(luaL_requiref, void , lua_State *L, const char *modname, lua_CFunction openf, int glb); - IMPORT_SYMBOL(luaL_buffinit, void , lua_State *L, luaL_Buffer *B); - IMPORT_SYMBOL(luaL_prepbuffsize, char *, luaL_Buffer *B, size_t sz); - IMPORT_SYMBOL(luaL_addlstring, void , luaL_Buffer *B, const char *s, size_t l); - IMPORT_SYMBOL(luaL_addstring, void , luaL_Buffer *B, const char *s); - IMPORT_SYMBOL(luaL_addvalue, void , luaL_Buffer *B); - IMPORT_SYMBOL(luaL_pushresult, void , luaL_Buffer *B); - IMPORT_SYMBOL(luaL_pushresultsize, void , luaL_Buffer *B, size_t sz); - IMPORT_SYMBOL(luaL_buffinitsize, char *, lua_State *L, luaL_Buffer *B, size_t sz); - IMPORT_SYMBOL(luaL_openlibs, void, lua_State* L); -} - -#endif /* LITE_XL_PLUGIN_ENTRYPOINT */ - -#endif /* LITE_XL_PLUGIN_API */ From a44a7eafe88f444fb7418cf0fbdfe01d8548aeec Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:33:34 +0800 Subject: [PATCH 059/148] Cross compiling improvements + macOS universal binary (#1458) * chore(resources): rename macos_arm64.txt to macos-arm64.txt This matches the platform-arch convention like many other parts of the project. * chore(resources/cross): rename wasm.txt to unknown-wasm32.txt * refactor(scripts/common.sh): use parameter expansion instead of if else * feat(scripts/common.sh): support custom arch and platform for get_default_build_dir * feat(scripts/build.sh): add --cross-platform, --cross-arch and --cross-file * feat(scripts/package.sh): add --cross-platform and --cross-arch * feat(build-packages.sh): add support for new options in build.sh and packages.sh * ci(build): make arm64 binaries in CI * ci(build): do not install external libraries * ci(build): fix invalid artifact name * ci(build): fix INSTALL_NAME * ci(build): change name for macos artifacts * ci(build): add script to build universal dmgs from individual dmgs * ci(build): build universal dmgs * fix(make-universal-binaries): fix wrong path for hdiutil * ci(build): rename macos action * fix(make-universal-binaries.sh): fix wrong pathname for ditto * ci(release): build macos universal binaries * ci(release): remove useless variables * ci(release): fix wrong dependency * ci(build): fix old ubuntu version This version will be restored once I complete some container-specific fixes. * ci(build): make build_macos_universal depend on release * ci(build): fix wrong dmg dir * style(ci): capitalize 'universal' for CI name * fix(make-universal-binaries.sh): fix truncated dmg name when it contains dots * ci: styling changes * ci(release): install appdmg only --- .github/workflows/build.yml | 51 ++++++++- .github/workflows/release.yml | 66 ++++++++++- build-packages.sh | 76 +++++++++---- .../{macos_arm64.txt => macos-arm64.txt} | 0 .../cross/{wasm.txt => unknown-wasm32.txt} | 0 scripts/build.sh | 103 +++++++++++++----- scripts/common.sh | 8 +- scripts/make-universal-binaries.sh | 33 ++++++ scripts/package.sh | 57 +++++++--- 9 files changed, 315 insertions(+), 79 deletions(-) rename resources/cross/{macos_arm64.txt => macos-arm64.txt} (100%) rename resources/cross/{wasm.txt => unknown-wasm32.txt} (100%) create mode 100644 scripts/make-universal-binaries.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 12247bfb..0dabaaa5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,11 +54,14 @@ jobs: path: ${{ env.INSTALL_NAME }}.tar.gz build_macos: - name: macOS (x86_64) + name: macOS runs-on: macos-11 env: CC: clang CXX: clang++ + strategy: + matrix: + arch: ['x86_64', 'arm64'] steps: - name: System Information run: | @@ -70,24 +73,60 @@ jobs: run: | echo "$HOME/.local/bin" >> "$GITHUB_PATH" echo "INSTALL_REF=${GITHUB_REF##*/}" >> "$GITHUB_ENV" - echo "INSTALL_NAME=lite-xl-${GITHUB_REF##*/}-macos-$(uname -m)" >> "$GITHUB_ENV" + echo "INSTALL_NAME=lite-xl-${GITHUB_REF##*/}-macos-${{ matrix.arch }}" >> "$GITHUB_ENV" + if [[ $(uname -m) != ${{ matrix.arch }} ]]; then echo "ARCH=--cross-arch ${{ matrix.arch }}" >> "$GITHUB_ENV"; fi - uses: actions/checkout@v3 - name: Python Setup uses: actions/setup-python@v4 with: python-version: 3.9 - name: Install Dependencies - run: bash scripts/install-dependencies.sh --debug + # --lhelper will eliminate a warning with arm64 and libusb + run: bash scripts/install-dependencies.sh --debug --lhelper - name: Build run: | bash --version - bash scripts/build.sh --bundle --debug --forcefallback + bash scripts/build.sh --bundle --debug --forcefallback $ARCH - name: Create DMG Image - run: bash scripts/package.sh --version ${INSTALL_REF} --debug --dmg + run: bash scripts/package.sh --version ${INSTALL_REF} $ARCH --debug --dmg - name: Upload DMG Image uses: actions/upload-artifact@v3 with: - name: macOS DMG Image + name: macOS DMG Images + path: ${{ env.INSTALL_NAME }}.dmg + + build_macos_universal: + name: macOS (Universal) + runs-on: macos-11 + needs: build_macos + steps: + - name: System Information + run: | + system_profiler SPSoftwareDataType + bash --version + gcc -v + xcodebuild -version + - name: Set Environment Variables + run: | + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + echo "INSTALL_NAME=lite-xl-${GITHUB_REF##*/}-macos-universal" >> "$GITHUB_ENV" + - uses: actions/checkout@v2 + - name: Download artifacts + uses: actions/download-artifact@v3 + id: download + with: + name: macOS DMG Images + path: dmgs-original + - name: Install appdmg + run: cd ~; npm i appdmg; cd - + - name: Make universal bundles + run: | + bash --version + bash scripts/make-universal-binaries.sh ${{ steps.download.outputs.download-path }} "${INSTALL_NAME}" + - name: Upload DMG Image + uses: actions/upload-artifact@v2 + with: + name: macOS Universal DMG Images path: ${{ env.INSTALL_NAME }}.dmg build_windows_msys2: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 47b826dd..206931c7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ on: jobs: release: name: Create Release - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest outputs: upload_url: ${{ steps.create_release.outputs.upload_url }} version: ${{ steps.tag.outputs.version }} @@ -49,7 +49,7 @@ jobs: build_linux: name: Linux needs: release - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest env: CC: gcc CXX: g++ @@ -115,6 +115,7 @@ jobs: echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" echo "INSTALL_NAME=lite-xl-${{ needs.release.outputs.version }}-macos-${{ matrix.arch }}" >> "$GITHUB_ENV" echo "INSTALL_NAME_ADDONS=lite-xl-${{ needs.release.outputs.version }}-addons-macos-${{ matrix.arch }}" >> "$GITHUB_ENV" + if [[ $(uname -m) != ${{ matrix.arch }} ]]; then echo "ARCH=--cross-arch ${{ matrix.arch }}" >> "$GITHUB_ENV"; fi - uses: actions/checkout@v3 - name: Python Setup uses: actions/setup-python@v4 @@ -125,11 +126,18 @@ jobs: - name: Build run: | bash --version - CROSS_ARCH=${{ matrix.arch }} bash scripts/build.sh --bundle --debug --forcefallback --release + bash scripts/build.sh --bundle --debug --forcefallback --release $ARCH - name: Create DMG Image run: | - CROSS_ARCH=${{ matrix.arch }} bash scripts/package.sh --version ${INSTALL_REF} --debug --dmg --release - CROSS_ARCH=${{ matrix.arch }} bash scripts/package.sh --version ${INSTALL_REF} --debug --addons --dmg --release + bash scripts/package.sh --version ${INSTALL_REF} $ARCH --debug --dmg --release + bash scripts/package.sh --version ${INSTALL_REF} $ARCH --debug --addons --dmg --release + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + with: + name: macOS DMG Images + path: | + ${{ env.INSTALL_NAME }}.dmg + ${{ env.INSTALL_NAME_ADDONS }}.dmg - name: Upload Files uses: softprops/action-gh-release@v1 with: @@ -139,6 +147,54 @@ jobs: ${{ env.INSTALL_NAME }}.dmg ${{ env.INSTALL_NAME_ADDONS }}.dmg + build_macos_universal: + name: macOS (Universal) + needs: [release, build_macos] + runs-on: macos-11 + steps: + - name: System Information + run: | + system_profiler SPSoftwareDataType + bash --version + gcc -v + xcodebuild -version + - name: Set Environment Variables + run: | + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + echo "INSTALL_BASE=lite-xl-${{ needs.release.outputs.version }}-macos" >> "$GITHUB_ENV" + echo "INSTALL_BASE_ADDONS=lite-xl-${{ needs.release.outputs.version }}-addons-macos" >> "$GITHUB_ENV" + - uses: actions/checkout@v2 + - name: Download Artifacts + uses: actions/download-artifact@v3 + id: download + with: + name: macOS DMG Images + path: dmgs-original + - name: Python Setup + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - name: Install appdmg + run: cd ~; npm i appdmg; cd - + - name: Prepare DMG Images + run: | + mkdir -p dmgs-addons dmgs-normal + mv -v "${{ steps.download.outputs.download-path }}/$INSTALL_BASE-"{x86_64,arm64}.dmg dmgs-normal + mv -v "${{ steps.download.outputs.download-path }}/$INSTALL_BASE_ADDONS-"{x86_64,arm64}.dmg dmgs-addons + - name: Create Universal DMGs + run: | + bash --version + bash scripts/make-universal-binaries.sh dmgs-normal "$INSTALL_BASE-universal" + bash scripts/make-universal-binaries.sh dmgs-addons "$INSTALL_BASE_ADDONS-universal" + - name: Upload Files + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ needs.release.outputs.version }} + draft: true + files: | + ${{ env.INSTALL_BASE }}-universal.dmg + ${{ env.INSTALL_BASE_ADDONS }}-universal.dmg + build_windows_msys2: name: Windows needs: release diff --git a/build-packages.sh b/build-packages.sh index 30a4ea2d..96a7d11d 100755 --- a/build-packages.sh +++ b/build-packages.sh @@ -13,33 +13,36 @@ show_help() { echo echo "Common options:" echo - echo "-h --help Show this help and exit." - echo "-b --builddir DIRNAME Set the name of the build directory (not path)." - echo " Default: '$(get_default_build_dir)'." - echo "-p --prefix PREFIX Install directory prefix." - echo " Default: '/'." - echo " --debug Debug this script." + echo "-h --help Show this help and exit." + echo "-b --builddir DIRNAME Set the name of the build directory (not path)." + echo " Default: '$(get_default_build_dir)'." + echo "-p --prefix PREFIX Install directory prefix." + echo " Default: '/'." + echo " --cross-platform PLATFORM The platform to cross compile for." + echo " --cross-arch ARCH The architecture to cross compile for." + echo " --debug Debug this script." echo echo "Build options:" echo - echo "-f --forcefallback Force to build subprojects dependencies statically." - echo "-B --bundle Create an App bundle (macOS only)" - echo "-P --portable Create a portable package." - echo "-O --pgo Use profile guided optimizations (pgo)." - echo " Requires running the application iteractively." + echo "-f --forcefallback Force to build subprojects dependencies statically." + echo "-B --bundle Create an App bundle (macOS only)" + echo "-P --portable Create a portable package." + echo "-O --pgo Use profile guided optimizations (pgo)." + echo " Requires running the application iteractively." + echo " --cross-file CROSS_FILE The cross file used for compiling." echo echo "Package options:" echo - echo "-d --destdir DIRNAME Set the name of the package directory (not path)." - echo " Default: 'lite-xl'." - echo "-v --version VERSION Sets the version on the package name." - echo "-A --appimage Create an AppImage (Linux only)." - echo "-D --dmg Create a DMG disk image (macOS only)." - echo " Requires NPM and AppDMG." - echo "-I --innosetup Create an InnoSetup installer (Windows only)." - echo "-r --release Compile in release mode." - echo "-S --source Create a source code package," - echo " including subprojects dependencies." + echo "-d --destdir DIRNAME Set the name of the package directory (not path)." + echo " Default: 'lite-xl'." + echo "-v --version VERSION Sets the version on the package name." + echo "-A --appimage Create an AppImage (Linux only)." + echo "-D --dmg Create a DMG disk image (macOS only)." + echo " Requires NPM and AppDMG." + echo "-I --innosetup Create an InnoSetup installer (Windows only)." + echo "-r --release Compile in release mode." + echo "-S --source Create a source code package," + echo " including subprojects dependencies." echo } @@ -60,6 +63,12 @@ main() { local portable local pgo local release + local cross_platform + local cross_platform_option=() + local cross_arch + local cross_arch_option=() + local cross_file + local cross_file_option=() for i in "$@"; do case $i in @@ -123,6 +132,21 @@ main() { pgo="--pgo" shift ;; + --cross-platform) + cross_platform="$2" + shift + shift + ;; + --cross-arch) + cross_arch="$2" + shift + shift + ;; + --cross-file) + cross_file="$2" + shift + shift + ;; --debug) debug="--debug" set -x @@ -143,10 +167,18 @@ main() { if [[ -n $dest_dir ]]; then dest_dir_option=("--destdir" "${dest_dir}"); fi if [[ -n $prefix ]]; then prefix_option=("--prefix" "${prefix}"); fi if [[ -n $version ]]; then version_option=("--version" "${version}"); fi + if [[ -n $cross_platform ]]; then cross_platform_option=("--cross-platform" "${cross_platform}"); fi + if [[ -n $cross_arch ]]; then cross_arch_option=("--cross-arch" "${cross_arch}"); fi + if [[ -n $cross_file ]]; then cross_file_option=("--cross-file" "${cross_file}"); fi + + source scripts/build.sh \ ${build_dir_option[@]} \ ${prefix_option[@]} \ + ${cross_platform_option[@]} \ + ${cross_arch_option[@]} \ + ${cross_file_option[@]} \ $debug \ $force_fallback \ $bundle \ @@ -159,6 +191,8 @@ main() { ${dest_dir_option[@]} \ ${prefix_option[@]} \ ${version_option[@]} \ + ${cross_platform_option[@]} \ + ${cross_arch_option[@]} \ --binary \ --addons \ $debug \ diff --git a/resources/cross/macos_arm64.txt b/resources/cross/macos-arm64.txt similarity index 100% rename from resources/cross/macos_arm64.txt rename to resources/cross/macos-arm64.txt diff --git a/resources/cross/wasm.txt b/resources/cross/unknown-wasm32.txt similarity index 100% rename from resources/cross/wasm.txt rename to resources/cross/unknown-wasm32.txt diff --git a/scripts/build.sh b/scripts/build.sh index 0cd4e8d8..778f596d 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -13,19 +13,26 @@ show_help() { echo echo "Available options:" echo - echo "-b --builddir DIRNAME Sets the name of the build directory (not path)." - echo " Default: '$(get_default_build_dir)'." - echo " --debug Debug this script." - echo "-f --forcefallback Force to build dependencies statically." - echo "-h --help Show this help and exit." - echo "-p --prefix PREFIX Install directory prefix. Default: '/'." - echo "-B --bundle Create an App bundle (macOS only)" - echo "-P --portable Create a portable binary package." - echo "-O --pgo Use profile guided optimizations (pgo)." - echo "-U --windows-lua-utf Use the UTF8 patch for Lua." - echo " macOS: disabled when used with --bundle," - echo " Windows: Implicit being the only option." - echo "-r --release Compile in release mode." + echo "-b --builddir DIRNAME Sets the name of the build directory (not path)." + echo " Default: '$(get_default_build_dir)'." + echo " --debug Debug this script." + echo "-f --forcefallback Force to build dependencies statically." + echo "-h --help Show this help and exit." + echo "-p --prefix PREFIX Install directory prefix. Default: '/'." + echo "-B --bundle Create an App bundle (macOS only)" + echo "-P --portable Create a portable binary package." + echo "-O --pgo Use profile guided optimizations (pgo)." + echo "-U --windows-lua-utf Use the UTF8 patch for Lua." + echo " macOS: disabled when used with --bundle," + echo " Windows: Implicit being the only option." + echo "-r --release Compile in release mode." + echo " --cross-platform PLATFORM Cross compile for this platform." + echo " The script will find the appropriate" + echo " cross file in 'resources/cross'." + echo " --cross-arch ARCH Cross compile for this architecture." + echo " The script will find the appropriate" + echo " cross file in 'resources/cross'." + echo " --cross-file CROSS_FILE Cross compile with the given cross file." echo } @@ -40,6 +47,10 @@ main() { local portable local pgo local patch_lua + local cross + local cross_platform + local cross_arch + local cross_file local lua_subproject_path @@ -87,6 +98,24 @@ main() { patch_lua="true" shift ;; + --cross-arch) + cross="true" + cross_arch="$2" + shift + shift + ;; + --cross-platform) + cross="true" + cross_platform="$2" + shift + shift + ;; + --cross-file) + cross="true" + cross_file="$2" + shift + shift + ;; -r|--release) build_type="release" shift @@ -107,19 +136,43 @@ main() { portable="" fi - if [[ $CROSS_ARCH != "" ]]; then - if [[ $platform == "macos" ]]; then - macos_version_min=10.11 - if [[ $CROSS_ARCH == "arm64" ]]; then - cross_file="--cross-file resources/cross/macos_arm64.txt" - macos_version_min=11.0 + # if CROSS_ARCH is used, it will be picked up + cross="${cross:-$CROSS_ARCH}" + if [[ -n "$cross" ]]; then + if [[ -n "$cross_file" ]] && ([[ -z "$cross_arch" ]] || [[ -z "$cross_platform" ]]); then + echo "Warning: --cross-platform or --cross-platform not set; guessing it from the filename." + # remove file extensions and directories from the path + cross_file_name="${cross_file##*/}" + cross_file_name="${cross_file_name%%.*}" + # cross_platform is the string before encountering the first hyphen + if [[ -z "$cross_platform" ]]; then + cross_platform="${cross_file_name%%-*}" + echo "Warning: Guessing --cross-platform $cross_platform" + fi + # cross_arch is the string after encountering the first hyphen + if [[ -z "$cross_arch" ]]; then + cross_arch="${cross_file_name#*-}" + echo "Warning: Guessing --cross-arch $cross_arch" fi - export MACOSX_DEPLOYMENT_TARGET=$macos_version_min - export MIN_SUPPORTED_MACOSX_DEPLOYMENT_TARGET=$macos_version_min - export CFLAGS=-mmacosx-version-min=$macos_version_min - export CXXFLAGS=-mmacosx-version-min=$macos_version_min - export LDFLAGS=-mmacosx-version-min=$macos_version_min fi + platform="${cross_platform:-$platform}" + arch="${cross_arch:-$arch}" + cross_file=("--cross-file" "${cross_file:-resources/cross/$platform-$arch.txt}") + # reload build_dir because platform and arch might change + build_dir="$(get_default_build_dir "$platform" "$arch")" + fi + + # arch and platform specific stuff + if [[ "$platform" == "macos" ]]; then + macos_version_min="10.11" + if [[ "$arch" == "arm64" ]]; then + macos_version_min="11.0" + fi + export MACOSX_DEPLOYMENT_TARGET="$macos_version_min" + export MIN_SUPPORTED_MACOSX_DEPLOYMENT_TARGET="$macos_version_min" + export CFLAGS="-mmacosx-version-min=$macos_version_min" + export CXXFLAGS="-mmacosx-version-min=$macos_version_min" + export LDFLAGS="-mmacosx-version-min=$macos_version_min" fi rm -rf "${build_dir}" @@ -137,7 +190,7 @@ main() { CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS meson setup \ --buildtype=$build_type \ --prefix "$prefix" \ - $cross_file \ + "${cross_file[@]}" \ $force_fallback \ $bundle \ $portable \ diff --git a/scripts/common.sh b/scripts/common.sh index 7078c99c..14402138 100644 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -75,22 +75,20 @@ get_platform_name() { get_platform_arch() { platform=$(get_platform_name) - arch=$(uname -m) + arch=${CROSS_ARCH:-$(uname -m)} if [[ $MSYSTEM != "" ]]; then if [[ $MSYSTEM == "MINGW64" ]]; then arch=x86_64 else arch=i686 fi - elif [[ $CROSS_ARCH != "" ]]; then - arch=$CROSS_ARCH fi echo "$arch" } get_default_build_dir() { - platform=$(get_platform_name) - arch=$(get_platform_arch) + platform="${1:-$(get_platform_name)}" + arch="${2:-$(get_platform_arch)}" echo "build-$platform-$arch" } diff --git a/scripts/make-universal-binaries.sh b/scripts/make-universal-binaries.sh new file mode 100644 index 00000000..e3f2d373 --- /dev/null +++ b/scripts/make-universal-binaries.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -ex + +if [ ! -e "src/api/api.h" ]; then + echo "Please run this script from the root directory of Lite XL." + exit 1 +fi + +WORKDIR="work" +DMGDIR="$1" + +if [[ -z "$DMGDIR" ]]; then + echo "Please provide a path containing the dmg files." + exit 1 +fi + +rm -rf "$WORKDIR" +mkdir -p "$WORKDIR" + +for dmg_path in "$DMGDIR"/*.dmg; do + dmg="${dmg_path##*/}" + dmg="${dmg%.dmg}" + hdiutil attach -mountpoint "/Volumes/$dmg" "$dmg_path" + if [[ ! -d "$WORKDIR/dmg" ]]; then + ditto "/Volumes/$dmg/Lite XL.app" "Lite XL.app" + fi + cp "/Volumes/$dmg/Lite XL.app/Contents/MacOS/lite-xl" "$WORKDIR/$dmg-lite-xl" + hdiutil detach "/Volumes/$dmg" +done + +lipo -create -output "Lite XL.app/Contents/MacOS/lite-xl" "$WORKDIR/"*-lite-xl + +source scripts/appdmg.sh "$2" \ No newline at end of file diff --git a/scripts/package.sh b/scripts/package.sh index 15dbd47f..d2346b76 100644 --- a/scripts/package.sh +++ b/scripts/package.sh @@ -13,23 +13,25 @@ show_help() { echo echo "Available options:" echo - echo "-b --builddir DIRNAME Sets the name of the build directory (not path)." - echo " Default: '$(get_default_build_dir)'." - echo "-d --destdir DIRNAME Set the name of the package directory (not path)." - echo " Default: 'lite-xl'." - echo "-h --help Show this help and exit." - echo "-p --prefix PREFIX Install directory prefix. Default: '/'." - echo "-v --version VERSION Sets the version on the package name." - echo "-a --addons Install 3rd party addons." - echo " --debug Debug this script." - echo "-A --appimage Create an AppImage (Linux only)." - echo "-B --binary Create a normal / portable package or macOS bundle," - echo " depending on how the build was configured. (Default.)" - echo "-D --dmg Create a DMG disk image with AppDMG (macOS only)." - echo "-I --innosetup Create a InnoSetup package (Windows only)." - echo "-r --release Strip debugging symbols." - echo "-S --source Create a source code package," - echo " including subprojects dependencies." + echo "-b --builddir DIRNAME Sets the name of the build directory (not path)." + echo " Default: '$(get_default_build_dir)'." + echo "-d --destdir DIRNAME Set the name of the package directory (not path)." + echo " Default: 'lite-xl'." + echo "-h --help Show this help and exit." + echo "-p --prefix PREFIX Install directory prefix. Default: '/'." + echo "-v --version VERSION Sets the version on the package name." + echo "-a --addons Install 3rd party addons." + echo " --debug Debug this script." + echo "-A --appimage Create an AppImage (Linux only)." + echo "-B --binary Create a normal / portable package or macOS bundle," + echo " depending on how the build was configured. (Default.)" + echo "-D --dmg Create a DMG disk image with AppDMG (macOS only)." + echo "-I --innosetup Create a InnoSetup package (Windows only)." + echo "-r --release Strip debugging symbols." + echo "-S --source Create a source code package," + echo " including subprojects dependencies." + echo " --cross-platform PLATFORM The platform to package for." + echo " --cross-arch ARCH The architecture to package for." echo } @@ -73,6 +75,9 @@ main() { local innosetup=false local release=false local source=false + local cross + local cross_arch + local cross_platform # store the current flags to easily pass them to appimage script local flags="$@" @@ -143,6 +148,18 @@ main() { addons=true shift ;; + --cross-platform) + cross=true + cross_platform="$2" + shift + shift + ;; + --cross-arch) + cross=true + cross_arch="$2" + shift + shift + ;; --debug) set -x shift @@ -159,6 +176,12 @@ main() { if [[ -n $1 ]]; then show_help; exit 1; fi + if [[ -n "$cross" ]]; then + platform="${cross_platform:-$platform}" + arch="${cross_arch:-$arch}" + build_dir="$(get_default_build_dir "$platform" "$arch")" + fi + # The source package doesn't require a previous build, # nor the following install step, so run it now. if [[ $source == true ]]; then source_package "lite-xl$version-src"; fi From 8e57b7111881c96112343b15b3ed8515dd32e414 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sat, 15 Apr 2023 03:45:46 +0800 Subject: [PATCH 060/148] refactor(plugin_api): move the header into include/ (#1440) --- resources/README.md | 4 ++-- resources/include/lite_xl_plugin_api.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/README.md b/resources/README.md index 975881c4..cf30432c 100644 --- a/resources/README.md +++ b/resources/README.md @@ -17,7 +17,7 @@ This folder contains resources that is used for building or packaging the projec ### Development -- `lite_xl_plugin_api.h`: Native plugin API header. See the contents of `lite_xl_plugin_api.h` for more details. +- `include/lite_xl_plugin_api.h`: Native plugin API header. See the contents of `lite_xl_plugin_api.h` for more details. -[1]: https://mesonbuild.com/Cross-compilation.html \ No newline at end of file +[1]: https://mesonbuild.com/Cross-compilation.html diff --git a/resources/include/lite_xl_plugin_api.h b/resources/include/lite_xl_plugin_api.h index 2947039e..0c5e93e9 100644 --- a/resources/include/lite_xl_plugin_api.h +++ b/resources/include/lite_xl_plugin_api.h @@ -2560,4 +2560,4 @@ void lite_xl_plugin_init(void *XL); * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -******************************************************************************/ \ No newline at end of file +******************************************************************************/ From 97f3159415969ad25158adcf18452120adec52e1 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 14 Apr 2023 23:49:26 +0200 Subject: [PATCH 061/148] Merge carets after `doc:move-to-{previous,next}-char` (#1462) --- data/core/commands/doc.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index d9803bce..0530f6e9 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -700,6 +700,7 @@ commands["doc:move-to-previous-char"] = function(dv) dv.doc:move_to_cursor(idx, translate.previous_char) end end + dv.doc:merge_cursors() end commands["doc:move-to-next-char"] = function(dv) @@ -710,6 +711,7 @@ commands["doc:move-to-next-char"] = function(dv) dv.doc:move_to_cursor(idx, translate.next_char) end end + dv.doc:merge_cursors() end command.add("core.docview", commands) From 64a6d886181bb3c5e5905d019434527e20360ad5 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sun, 16 Apr 2023 21:18:40 +0800 Subject: [PATCH 062/148] Build releases with Ubuntu 18.04 container (#1460) * ci(release): try using lite-xl-build-box * ci(build): test with my own fork * ci(build): do not install python via actions * ci(build): disable package updates * fix(scripts/appimage.sh): add workaround for non-FUSE environments * ci(build): document why the actions are disabled * ci(release): fix typo --- .github/workflows/release.yml | 11 +++++++++++ scripts/appimage.sh | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 206931c7..581b6469 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,6 +50,7 @@ jobs: name: Linux needs: release runs-on: ubuntu-latest + container: ghcr.io/takase1121/lite-xl-build-box:latest env: CC: gcc CXX: g++ @@ -59,16 +60,26 @@ jobs: echo "$HOME/.local/bin" >> "$GITHUB_PATH" echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" - uses: actions/checkout@v3 + + # disabled because this will break our own Python install - name: Python Setup + if: false uses: actions/setup-python@v4 with: python-version: 3.9 + + # disabled because the container has up-to-date packages - name: Update Packages + if: false run: sudo apt-get update + + # disabled as the dependencies are already installed - name: Install Dependencies + if: false run: | bash scripts/install-dependencies.sh --debug sudo apt-get install -y ccache + - name: Build Portable run: | bash --version diff --git a/scripts/appimage.sh b/scripts/appimage.sh index 03de616c..17551a48 100644 --- a/scripts/appimage.sh +++ b/scripts/appimage.sh @@ -181,7 +181,7 @@ generate_appimage() { version="${version}-addons" fi - ./appimagetool LiteXL.AppDir LiteXL${version}-${ARCH}.AppImage + ./appimagetool --appimage-extract-and-run LiteXL.AppDir LiteXL${version}-${ARCH}.AppImage } setup_appimagetool From 2fe1f52a1f5a5d690452d547f8ab482ce16adeae Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Tue, 18 Apr 2023 02:56:04 +0800 Subject: [PATCH 063/148] Process API improvements (again) (#1370) * feat(process): add push_error * refactor(process): use push_error for better errors * style(process): consistent error messages * refactor(process): reimplement process.strerror() with push_error * refactor(process): implement close_fd only once * refactor(process): rename process_handle to process_handle_t * fix(process): prevent errors from a NULL error message * refactor(process): refactor push_error into 2 functions * fix(process): fix wrong error message * fix(process): check if push_error_string actually pushed something * refactor(process): make error messages descriptive * fix(process): check for empty table instead of aborting * refactor(process): make error messages descriptive on Windows * refactor(process): rename process_stream_handle to process_stream_t * refactor(process): fix wrong usage of process_handle_t * fix(process): fix wrong type name * refactor(process): incoporate kill_list_thread into process_kill_list_t * refactor(process): make kill_list per-state data --- src/api/process.c | 181 +++++++++++++++++++++++++++++++--------------- 1 file changed, 121 insertions(+), 60 deletions(-) diff --git a/src/api/process.c b/src/api/process.c index 2b0a5008..2e343c6c 100644 --- a/src/api/process.c +++ b/src/api/process.c @@ -24,13 +24,28 @@ #define READ_BUF_SIZE 2048 #define PROCESS_TERM_TRIES 3 #define PROCESS_TERM_DELAY 50 +#define PROCESS_KILL_LIST_NAME "__process_kill_list__" #if _WIN32 -typedef HANDLE process_stream_handle; -typedef HANDLE process_handle; + +typedef DWORD process_error_t; +typedef HANDLE process_stream_t; +typedef HANDLE process_handle_t; + +#define HANDLE_INVALID (INVALID_HANDLE_VALUE) +#define PROCESS_GET_HANDLE(P) ((P)->process_information.hProcess) + +static volatile long PipeSerialNumber; + #else -typedef int process_stream_handle; -typedef pid_t process_handle; + +typedef int process_error_t; +typedef int process_stream_t; +typedef pid_t process_handle_t; + +#define HANDLE_INVALID (0) +#define PROCESS_GET_HANDLE(P) ((P)->pid) + #endif typedef struct { @@ -43,13 +58,13 @@ typedef struct { bool reading[2]; char buffer[2][READ_BUF_SIZE]; #endif - process_stream_handle child_pipes[3][2]; + process_stream_t child_pipes[3][2]; } process_t; typedef struct process_kill_s { int tries; uint32_t start_time; - process_handle handle; + process_handle_t handle; struct process_kill_s *next; } process_kill_t; @@ -57,6 +72,7 @@ typedef struct { bool stop; SDL_mutex *mutex; SDL_cond *has_work, *work_done; + SDL_Thread *worker_thread; process_kill_t *head; process_kill_t *tail; } process_kill_list_t; @@ -83,21 +99,24 @@ typedef enum { REDIRECT_PARENT = -3, } filed_e; -static process_kill_list_t kill_list = { 0 }; -static SDL_Thread *kill_list_thread = NULL; - +static void close_fd(process_stream_t *handle) { + if (*handle) { #ifdef _WIN32 - static volatile long PipeSerialNumber; - static void close_fd(HANDLE* handle) { if (*handle) CloseHandle(*handle); *handle = INVALID_HANDLE_VALUE; } - #define PROCESS_GET_HANDLE(P) ((P)->process_information.hProcess) + CloseHandle(*handle); #else - static void close_fd(int* fd) { if (*fd) close(*fd); *fd = 0; } - #define PROCESS_GET_HANDLE(P) ((P)->pid) + close(*handle); #endif + *handle = HANDLE_INVALID; + } +} + + +static int kill_list_worker(void *ud); static void kill_list_free(process_kill_list_t *list) { process_kill_t *node, *temp; + SDL_WaitThread(list->worker_thread, NULL); SDL_DestroyMutex(list->mutex); SDL_DestroyCond(list->has_work); SDL_DestroyCond(list->work_done); @@ -107,10 +126,12 @@ static void kill_list_free(process_kill_list_t *list) { node = node->next; free(temp); } + memset(list, 0, sizeof(process_kill_list_t)); } static bool kill_list_init(process_kill_list_t *list) { + memset(list, 0, sizeof(process_kill_list_t)); list->mutex = SDL_CreateMutex(); list->has_work = SDL_CreateCond(); list->work_done = SDL_CreateCond(); @@ -120,6 +141,11 @@ static bool kill_list_init(process_kill_list_t *list) { kill_list_free(list); return false; } + list->worker_thread = SDL_CreateThread(kill_list_worker, "process_kill", list); + if (!list->worker_thread) { + kill_list_free(list); + return false; + } return true; } @@ -157,7 +183,7 @@ static void kill_list_wait_all(process_kill_list_t *list) { } -static void process_handle_close(process_handle *handle) { +static void process_handle_close(process_handle_t *handle) { #ifdef _WIN32 if (*handle) { CloseHandle(*handle); @@ -168,7 +194,7 @@ static void process_handle_close(process_handle *handle) { } -static bool process_handle_is_running(process_handle handle, int *status) { +static bool process_handle_is_running(process_handle_t handle, int *status) { #ifdef _WIN32 DWORD s; if (GetExitCodeProcess(handle, &s) && s != STILL_ACTIVE) { @@ -188,7 +214,7 @@ static bool process_handle_is_running(process_handle handle, int *status) { } -static bool process_handle_signal(process_handle handle, signal_e sig) { +static bool process_handle_signal(process_handle_t handle, signal_e sig) { #if _WIN32 switch(sig) { case SIGNAL_TERM: return GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, GetProcessId(handle)); @@ -252,6 +278,37 @@ static int kill_list_worker(void *ud) { } +static int push_error_string(lua_State *L, process_error_t err) { +#ifdef _WIN32 + char *msg = NULL; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (char *) &msg, + 0, + NULL); + if (!msg) + return 0; + + lua_pushstring(L, msg); + LocalFree(msg); +#else + lua_pushstring(L, strerror(err)); +#endif + return 1; +} + +static void push_error(lua_State *L, const char *extra, process_error_t err) { + const char *msg = "unknown error"; + extra = extra != NULL ? extra : "error"; + if (push_error_string(L, err)) + msg = lua_tostring(L, -1); + lua_pushfstring(L, "%s: %s (%d)", extra, msg, err); +} + static bool poll_process(process_t* proc, int timeout) { uint32_t ticks; @@ -296,6 +353,10 @@ static int process_start(lua_State* L) { lua_pushinteger(L, (int)lua_objlen(L, 1)); #endif cmd_len = luaL_checknumber(L, -1); lua_pop(L, 1); + if (!cmd_len) + // we have not allocated anything here yet, so we can skip cleanup code + // don't do this anywhere else! + return luaL_argerror(L, 1,"table cannot be empty"); for (size_t i = 1; i <= cmd_len; ++i) { lua_pushinteger(L, i); lua_rawget(L, 1); @@ -306,9 +367,6 @@ static int process_start(lua_State* L) { cmd[0] = luaL_checkstring(L, 1); cmd_len = 1; } - // this should never trip - // but if it does we are in deep trouble - assert(cmd[0]); if (arg_len > 1) { lua_getfield(L, 2, "env"); @@ -334,7 +392,7 @@ static int process_start(lua_State* L) { lua_getfield(L, 2, "stderr"); new_fds[STDERR_FD] = luaL_optnumber(L, -1, STDERR_FD); for (int stream = STDIN_FD; stream <= STDERR_FD; ++stream) { if (new_fds[stream] > STDERR_FD || new_fds[stream] < REDIRECT_PARENT) { - lua_pushfstring(L, "redirect to handles, FILE* and paths are not supported"); + lua_pushfstring(L, "error: redirect to handles, FILE* and paths are not supported"); retval = -1; goto cleanup; } @@ -368,20 +426,22 @@ static int process_start(lua_State* L) { self->child_pipes[i][0] = CreateNamedPipeA(pipeNameBuffer, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, 1, READ_BUF_SIZE, READ_BUF_SIZE, 0, NULL); if (self->child_pipes[i][0] == INVALID_HANDLE_VALUE) { - lua_pushfstring(L, "Error creating read pipe: %d.", GetLastError()); + push_error(L, "cannot create pipe", GetLastError()); retval = -1; goto cleanup; } self->child_pipes[i][1] = CreateFileA(pipeNameBuffer, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (self->child_pipes[i][1] == INVALID_HANDLE_VALUE) { + // prevent CloseHandle from messing up error codes + DWORD err = GetLastError(); CloseHandle(self->child_pipes[i][0]); - lua_pushfstring(L, "Error creating write pipe: %d.", GetLastError()); + push_error(L, "cannot open pipe", err); retval = -1; goto cleanup; } if (!SetHandleInformation(self->child_pipes[i][i == STDIN_FD ? 1 : 0], HANDLE_FLAG_INHERIT, 0) || !SetHandleInformation(self->child_pipes[i][i == STDIN_FD ? 0 : 1], HANDLE_FLAG_INHERIT, 1)) { - lua_pushfstring(L, "Error inheriting pipes: %d.", GetLastError()); + push_error(L, "cannot set pipe permission", GetLastError()); retval = -1; goto cleanup; } @@ -445,7 +505,7 @@ static int process_start(lua_State* L) { if (env_len > 0) MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, environmentBlock, offset, (LPWSTR)wideEnvironmentBlock, sizeof(wideEnvironmentBlock)); if (!CreateProcess(NULL, commandLine, NULL, NULL, true, (detach ? DETACHED_PROCESS : CREATE_NO_WINDOW) | CREATE_UNICODE_ENVIRONMENT, env_len > 0 ? wideEnvironmentBlock : NULL, cwd, &siStartInfo, &self->process_information)) { - lua_pushfstring(L, "Error creating a process: %d.", GetLastError()); + push_error(L, NULL, GetLastError()); retval = -1; goto cleanup; } @@ -457,7 +517,7 @@ static int process_start(lua_State* L) { int control_pipe[2] = { 0 }; for (int i = 0; i < 3; ++i) { // Make only the parents fd's non-blocking. Children should block. if (pipe(self->child_pipes[i]) || fcntl(self->child_pipes[i][i == STDIN_FD ? 1 : 0], F_SETFL, O_NONBLOCK) == -1) { - lua_pushfstring(L, "Error creating pipes: %s", strerror(errno)); + push_error(L, "cannot create pipe", errno); retval = -1; goto cleanup; } @@ -476,7 +536,7 @@ static int process_start(lua_State* L) { self->pid = (long)fork(); if (self->pid < 0) { - lua_pushfstring(L, "Error running fork: %s.", strerror(errno)); + push_error(L, "cannot create child process", errno); retval = -1; goto cleanup; } else if (!self->pid) { @@ -533,7 +593,7 @@ static int process_start(lua_State* L) { free((char*)env_values[i]); } for (int stream = 0; stream < 3; ++stream) { - process_stream_handle* pipe = &self->child_pipes[stream][stream == STDIN_FD ? 0 : 1]; + process_stream_t* pipe = &self->child_pipes[stream][stream == STDIN_FD ? 0 : 1]; if (*pipe) { close_fd(pipe); } @@ -549,7 +609,7 @@ static int g_read(lua_State* L, int stream, unsigned long read_size) { process_t* self = (process_t*) luaL_checkudata(L, 1, API_TYPE_PROCESS); long length = 0; if (stream != STDOUT_FD && stream != STDERR_FD) - return luaL_error(L, "redirect to handles, FILE* and paths are not supported"); + return luaL_error(L, "error: redirect to handles, FILE* and paths are not supported"); #if _WIN32 int writable_stream_idx = stream - 1; if (self->reading[writable_stream_idx] || !ReadFile(self->child_pipes[stream][0], self->buffer[writable_stream_idx], READ_BUF_SIZE, NULL, &self->overlapped[writable_stream_idx])) { @@ -597,9 +657,9 @@ static int f_write(lua_State* L) { #if _WIN32 DWORD dwWritten; if (!WriteFile(self->child_pipes[STDIN_FD][1], data, data_size, &dwWritten, NULL)) { - int lastError = GetLastError(); + push_error(L, NULL, GetLastError()); signal_process(self, SIGNAL_TERM); - return luaL_error(L, "error writing to process: %d", lastError); + return lua_error(L); } length = dwWritten; #else @@ -607,9 +667,9 @@ static int f_write(lua_State* L) { if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) length = 0; else if (length < 0) { - const char* lastError = strerror(errno); + push_error(L, "cannot write to child process", errno); signal_process(self, SIGNAL_TERM); - return luaL_error(L, "error writing to process: %s", lastError); + return lua_error(L); } #endif lua_pushinteger(L, length); @@ -626,15 +686,7 @@ static int f_close_stream(lua_State* L) { // Generic stuff below here. static int process_strerror(lua_State* L) { - #if _WIN32 - return 1; - #endif - int error_code = luaL_checknumber(L, 1); - if (error_code < 0) - lua_pushstring(L, strerror(error_code)); - else - lua_pushnil(L); - return 1; + return push_error_string(L, luaL_checknumber(L, 1)); } static int f_tostring(lua_State* L) { @@ -688,30 +740,32 @@ static int f_kill(lua_State* L) { return self_signal(L, SIGNAL_KILL); } static int f_interrupt(lua_State* L) { return self_signal(L, SIGNAL_INTERRUPT); } static int f_gc(lua_State* L) { + process_kill_list_t *list = NULL; + process_kill_t *p = NULL; process_t* self = (process_t*) luaL_checkudata(L, 1, API_TYPE_PROCESS); - if (poll_process(self, 0) && !self->detached) { - // attempt to kill the process if not detached - process_kill_t *p; + // get the kill_list for the lua_State + if (lua_getfield(L, LUA_REGISTRYINDEX, PROCESS_KILL_LIST_NAME) == LUA_TUSERDATA) + list = (process_kill_list_t *) lua_touserdata(L, -1); + if (poll_process(self, 0) && !self->detached) { + // attempt to kill the process if still running and not detached signal_process(self, SIGNAL_TERM); - p = malloc(sizeof(process_kill_t)); - if (!p || !kill_list_thread) { - // if we can't allocate, we'll use the old method - poll_process(self, PROCESS_TERM_DELAY); - if (self->running) { + if (!list || !list->worker_thread || !(p = malloc(sizeof(process_kill_t)))) { + // use synchronous waiting + if (poll_process(self, PROCESS_TERM_DELAY)) { signal_process(self, SIGNAL_KILL); poll_process(self, PROCESS_TERM_DELAY); } } else { - // send the handle to a queue for asynchronous waiting + // put the handle into a queue for asynchronous waiting p->handle = PROCESS_GET_HANDLE(self); p->start_time = SDL_GetTicks(); p->tries = 1; - SDL_LockMutex(kill_list.mutex); - kill_list_push(&kill_list, p); - SDL_CondSignal(kill_list.has_work); - SDL_UnlockMutex(kill_list.mutex); + SDL_LockMutex(list->mutex); + kill_list_push(list, p); + SDL_CondSignal(list->has_work); + SDL_UnlockMutex(list->mutex); } } close_fd(&self->child_pipes[STDIN_FD ][1]); @@ -727,9 +781,13 @@ static int f_running(lua_State* L) { } static int process_gc(lua_State *L) { - kill_list_wait_all(&kill_list); - SDL_WaitThread(kill_list_thread, NULL); - kill_list_free(&kill_list); + process_kill_list_t *list = NULL; + // get the kill_list for the lua_State + if (lua_getfield(L, LUA_REGISTRYINDEX, PROCESS_KILL_LIST_NAME) == LUA_TUSERDATA) { + list = (process_kill_list_t *) lua_touserdata(L, -1); + kill_list_wait_all(list); + kill_list_free(list); + } return 0; } @@ -758,8 +816,11 @@ static const struct luaL_Reg lib[] = { }; int luaopen_process(lua_State *L) { - if (kill_list_init(&kill_list)) - kill_list_thread = SDL_CreateThread(kill_list_worker, "process_kill", &kill_list); + process_kill_list_t *list = lua_newuserdata(L, sizeof(process_kill_list_t)); + if (kill_list_init(list)) + lua_setfield(L, LUA_REGISTRYINDEX, PROCESS_KILL_LIST_NAME); + else + lua_pop(L, 1); // discard the list // create the process metatable luaL_newmetatable(L, API_TYPE_PROCESS); From 760271d41667d0d9b5759ac6ed9bd4ee7d66aa9e Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 18 Apr 2023 20:55:25 +0200 Subject: [PATCH 064/148] Make `system.path_compare` more digit-aware (#1474) This allows a human friendly sorting filenames with numbers in them So - asd1 - asd10 - asd2 becomes - asd1 - asd2 - asd10 --- src/api/system.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/api/system.c b/src/api/system.c index b8a27d39..9e3fb5ab 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -1052,9 +1052,10 @@ static int f_path_compare(lua_State *L) { int type1 = strcmp(type1_s, "dir") != 0; int type2 = strcmp(type2_s, "dir") != 0; /* Find the index of the common part of the path. */ - int offset = 0, i; + size_t offset = 0, i, j; for (i = 0; i < len1 && i < len2; i++) { if (path1[i] != path2[i]) break; + if (isdigit(path1[i])) break; if (path1[i] == PATHSEP) { offset = i + 1; } @@ -1074,21 +1075,37 @@ static int f_path_compare(lua_State *L) { } /* If types are the same compare the files' path alphabetically. */ int cfr = -1; - int len_min = (len1 < len2 ? len1 : len2); bool same_len = len1 == len2; - for (int j = offset; j <= len_min; j++) { - if (path1[j] == 0 || path2[j] == 0) { + for (i = offset, j = offset; i <= len1 && j <= len2; i++, j++) { + if (path1[i] == 0 || path2[j] == 0) { if (cfr < 0) cfr = 0; // The strings are equal if (!same_len) { - cfr = (path1[j] == 0); + cfr = (path1[i] == 0); } - } else if (path1[j] == path2[j]) { + } else if (isdigit(path1[i]) && isdigit(path2[j])) { + size_t ii = 0, ij = 0; + while (isdigit(path1[i+ii])) { ii++; } + while (isdigit(path2[j+ij])) { ij++; } + + size_t di = 0, dj = 0; + for (size_t ai = 0; ai < ii; ++ai) { + di = di * 10 + (path1[i+ai] - '0'); + } + for (size_t aj = 0; aj < ij; ++aj) { + dj = dj * 10 + (path2[j+aj] - '0'); + } + + if (di == dj) { + continue; + } + cfr = (di < dj); + } else if (path1[i] == path2[j]) { continue; - } else if (path1[j] == PATHSEP || path2[j] == PATHSEP) { + } else if (path1[i] == PATHSEP || path2[j] == PATHSEP) { /* For comparison we treat PATHSEP as if it was the string terminator. */ - cfr = (path1[j] == PATHSEP); + cfr = (path1[i] == PATHSEP); } else { - char a = path1[j], b = path2[j]; + char a = path1[i], b = path2[j]; if (a >= 'A' && a <= 'Z') a += 32; if (b >= 'A' && b <= 'Z') b += 32; if (a == b) { @@ -1096,7 +1113,7 @@ static int f_path_compare(lua_State *L) { to keep the first case sensitive difference. */ if (same_len && cfr < 0) { /* Give priority to lower-case characters */ - cfr = (path1[j] > path2[j]); + cfr = (path1[i] > path2[j]); } continue; } From 1952848caaddbd9765e9177de39418ae6ed4bdb7 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Wed, 19 Apr 2023 09:02:10 +0800 Subject: [PATCH 065/148] fix(process): check for HANDLE_INVALID (#1475) --- src/api/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/process.c b/src/api/process.c index 2e343c6c..d7bfeb72 100644 --- a/src/api/process.c +++ b/src/api/process.c @@ -100,7 +100,7 @@ typedef enum { } filed_e; static void close_fd(process_stream_t *handle) { - if (*handle) { + if (*handle && *handle != HANDLE_INVALID) { #ifdef _WIN32 CloseHandle(*handle); #else From 2517d34113dd9874d47beaba0f60da6f1d1c53c9 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Wed, 19 Apr 2023 09:14:03 +0800 Subject: [PATCH 066/148] ci(build): update action dependencies --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0dabaaa5..398aae67 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -110,7 +110,7 @@ jobs: run: | echo "$HOME/.local/bin" >> "$GITHUB_PATH" echo "INSTALL_NAME=lite-xl-${GITHUB_REF##*/}-macos-universal" >> "$GITHUB_ENV" - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Download artifacts uses: actions/download-artifact@v3 id: download @@ -124,7 +124,7 @@ jobs: bash --version bash scripts/make-universal-binaries.sh ${{ steps.download.outputs.download-path }} "${INSTALL_NAME}" - name: Upload DMG Image - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: macOS Universal DMG Images path: ${{ env.INSTALL_NAME }}.dmg @@ -191,7 +191,7 @@ jobs: - uses: ilammy/msvc-dev-cmd@v1 with: arch: ${{ matrix.arch.target }} - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 with: python-version: '3.x' - name: Install meson and ninja From 793af14dca7e7d3137f992c4fba5ce5e8d108d63 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Sat, 22 Apr 2023 14:54:42 -0400 Subject: [PATCH 067/148] Fixing linewrapping bug to do with wordwrapping. --- data/plugins/linewrapping.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/data/plugins/linewrapping.lua b/data/plugins/linewrapping.lua index b287c523..e461ae52 100644 --- a/data/plugins/linewrapping.lua +++ b/data/plugins/linewrapping.lua @@ -485,7 +485,7 @@ local old_draw_line_body = DocView.draw_line_body function DocView:draw_line_body(line, x, y) if not self.wrapped_settings then return old_draw_line_body(self, line, x, y) end local lh = self:get_line_height() - local idx0 = get_line_idx_col_count(self, line) + local idx0, _, count = get_line_idx_col_count(self, line) for lidx, line1, col1, line2, col2 in self.doc:get_selections(true) do if line >= line1 and line <= line2 then if line1 ~= line then col1 = 1 end @@ -493,12 +493,14 @@ function DocView:draw_line_body(line, x, y) if col1 ~= col2 then local idx1, ncol1 = get_line_idx_col_count(self, line, col1) local idx2, ncol2 = get_line_idx_col_count(self, line, col2) + local start = 0 for i = idx1, idx2 do local x1, x2 = x + (idx1 == i and self:get_col_x_offset(line1, col1) or 0) if idx2 == i then x2 = x + self:get_col_x_offset(line, col2) else - x2 = x + self:get_col_x_offset(line, get_idx_line_length(self, i, line) + 1, true) + start = start + get_idx_line_length(self, i, line) + x2 = x + self:get_col_x_offset(line, start + 1, true) end renderer.draw_rect(x1, y + (i - idx0) * lh, x2 - x1, lh, style.selection) end @@ -514,7 +516,6 @@ function DocView:draw_line_body(line, x, y) end end if draw_highlight then - local _, _, count = get_line_idx_col_count(self, line) for i=1,count do self:draw_line_highlight(x + self.scroll.x, y + lh * (i - 1)) end From 6111b071ecbd2c087ce0c91f9af30d63a4859c95 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sun, 23 Apr 2023 16:35:40 +0800 Subject: [PATCH 068/148] fix(rencache): fix compiler warning for printing size_t --- src/rencache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rencache.c b/src/rencache.c index 928d0b0d..52527969 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -142,7 +142,7 @@ static void* push_command(enum CommandType type, int size) { int n = command_buf_idx + size; while (n > command_buf_size) { if (!expand_command_buffer()) { - fprintf(stderr, "Warning: (" __FILE__ "): unable to resize command buffer (%ld)\n", + fprintf(stderr, "Warning: (" __FILE__ "): unable to resize command buffer (%zu)\n", (size_t)(command_buf_size * CMD_BUF_RESIZE_RATE)); resize_issue = true; return NULL; From c0b1fe348fde2695f2d4b65ea17c9bea49624a18 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Wed, 26 Apr 2023 08:29:57 +0800 Subject: [PATCH 069/148] feat(bootstrap): return error string from C searcher --- data/core/start.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/core/start.lua b/data/core/start.lua index d504108a..a0edbe54 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -35,8 +35,8 @@ package.cpath = package.native_plugins = {} package.searchers = { package.searchers[1], package.searchers[2], function(modname) - local path = package.searchpath(modname, package.cpath) - if not path then return nil end + local path, err = package.searchpath(modname, package.cpath) + if not path then return err end return system.load_native_plugin, path end } From bd36b3f6156460e940ff94d37de2d30d3098c776 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Sat, 29 Apr 2023 18:50:39 +0200 Subject: [PATCH 070/148] Restore horizontal scroll position after scale change (#494) * Restore horizontal scroll position after scale change * Consider `View` horizontal size when restoring horizontal scroll This is needed because `View:get_h_scrollable_size` includes the horizontal size, while `View.scroll.x` doesn't. --- data/plugins/scale.lua | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/data/plugins/scale.lua b/data/plugins/scale.lua index 7c9e6d4c..89a016b7 100644 --- a/data/plugins/scale.lua +++ b/data/plugins/scale.lua @@ -25,11 +25,16 @@ local function set_scale(scale) scale = common.clamp(scale, 0.2, 6) -- save scroll positions - local scrolls = {} + local v_scrolls = {} + local h_scrolls = {} for _, view in ipairs(core.root_view.root_node:get_children()) do local n = view:get_scrollable_size() - if n ~= math.huge and not view:is(CommandView) and n > view.size.y then - scrolls[view] = view.scroll.y / (n - view.size.y) + if n ~= math.huge and n > view.size.y then + v_scrolls[view] = view.scroll.y / (n - view.size.y) + end + local hn = view:get_h_scrollable_size() + if hn ~= math.huge and hn > view.size.x then + h_scrolls[view] = view.scroll.x / (hn - view.size.x) end end @@ -59,10 +64,14 @@ local function set_scale(scale) end -- restore scroll positions - for view, n in pairs(scrolls) do + for view, n in pairs(v_scrolls) do view.scroll.y = n * (view:get_scrollable_size() - view.size.y) view.scroll.to.y = view.scroll.y end + for view, hn in pairs(h_scrolls) do + view.scroll.x = hn * (view:get_h_scrollable_size() - view.size.x) + view.scroll.to.x = view.scroll.x + end core.redraw = true end From 4c320a10c02868c99d691622ecee5f274d6b27c5 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sat, 13 May 2023 18:29:20 +0800 Subject: [PATCH 071/148] docs(system): make all parameters for set_window_hit_test optional --- docs/api/system.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/api/system.lua b/docs/api/system.lua index 17c379fa..ffbc6f42 100644 --- a/docs/api/system.lua +++ b/docs/api/system.lua @@ -107,10 +107,12 @@ function system.set_window_bordered(bordered) end ---When then window is run borderless (without system decorations), this ---function allows to set the size of the different regions that allow ---for custom window management. +---To disable custom window management, call this function without any +---arguments --- ----@param title_height number ----@param controls_width number Width of window controls (maximize,minimize and close buttons, etc). ----@param resize_border number The amount of pixels reserved for resizing +---@param title_height? number Height of the window decoration +---@param controls_width? number Width of window controls (maximize,minimize and close buttons, etc). +---@param resize_border? number The amount of pixels reserved for resizing function system.set_window_hit_test(title_height, controls_width, resize_border) end --- From 64e5fd8ead686ec280eb8ea926d61de66bc52308 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Tue, 16 May 2023 21:18:04 +0800 Subject: [PATCH 072/148] fix(renderer): fix memory leak when freeing glyphsets --- src/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer.c b/src/renderer.c index e9e715ef..6d14ea44 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -203,7 +203,7 @@ static RenFont* font_group_get_glyph(GlyphSet** set, GlyphMetric** metric, RenFo static void font_clear_glyph_cache(RenFont* font) { for (int i = 0; i < SUBPIXEL_BITMAPS_CACHED; ++i) { - for (int j = 0; j < MAX_GLYPHSET; ++j) { + for (int j = 0; j < MAX_LOADABLE_GLYPHSETS; ++j) { if (font->sets[i][j]) { if (font->sets[i][j]->surface) SDL_FreeSurface(font->sets[i][j]->surface); From 2a9b367e13229dc4afc74a996cb6dff6f6a08fdc Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sat, 19 Aug 2023 13:26:01 +0800 Subject: [PATCH 073/148] Move lineguide below blinking cursor, fixes #1488 (#1511) * Move lineguide below blinking cursor, fixes #1488 * Added config_spec custom color --- data/plugins/lineguide.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/plugins/lineguide.lua b/data/plugins/lineguide.lua index 63f9a9ca..da9f9b97 100644 --- a/data/plugins/lineguide.lua +++ b/data/plugins/lineguide.lua @@ -79,8 +79,6 @@ end local draw_overlay = DocView.draw_overlay function DocView:draw_overlay(...) - draw_overlay(self, ...) - if type(config.plugins.lineguide) == "table" and @@ -106,6 +104,8 @@ function DocView:draw_overlay(...) end end end + -- everything else like the cursor above the line guides + draw_overlay(self, ...) end command.add(nil, { From 6c17f6e2ee124267fbecbd2764d59054940444b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jefferson=20Gonz=C3=A1lez?= Date: Fri, 19 May 2023 10:28:39 -0700 Subject: [PATCH 074/148] Close lua state when exiting on a runtime error (#1487) * Close lua state when exiting on a runtime error * This change allows calling the garbage collector before exiting the application for a cleaner shutdown. * Components like the shared memory object on #1486 will have a better chance at destroying no longer needed resources. * Overriden os.exit to always close the state * Allow setting close param on os.exit override * Simplified the os.exit override a bit more Co-authored-by: Guldoman --------- Co-authored-by: Guldoman --- src/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.c b/src/main.c index c068421b..468fb568 100644 --- a/src/main.c +++ b/src/main.c @@ -225,6 +225,10 @@ init_lua: const char *init_lite_code = \ "local core\n" + "local os_exit = os.exit\n" + "os.exit = function(code, close)\n" + " os_exit(code, close == nil and true or close)\n" + "end\n" "xpcall(function()\n" " local match = require('utf8extra').match\n" " HOME = os.getenv('" LITE_OS_HOME "')\n" From 3febcf454c2cb5dbfcc90bb076c628713c87c477 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 24 May 2023 04:23:27 +0200 Subject: [PATCH 075/148] Mark `linewrapping` `open_files` table as weak We weren't correctly garbage-collecting `Doc`s, so we had `Highlighter`s stay alive over their due time. --- data/plugins/linewrapping.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/plugins/linewrapping.lua b/data/plugins/linewrapping.lua index e461ae52..62412720 100644 --- a/data/plugins/linewrapping.lua +++ b/data/plugins/linewrapping.lua @@ -310,7 +310,7 @@ local function get_line_col_from_index_and_x(docview, idx, x) end -local open_files = {} +local open_files = setmetatable({ }, { __mode = "k" }) local old_doc_insert = Doc.raw_insert function Doc:raw_insert(line, col, text, undo_stack, time) From ff884d7d4ad83ad2541be12b8d7afaf1ce68c325 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 9 Jun 2023 03:50:34 +0200 Subject: [PATCH 076/148] When logging don't use `core.status_view` if not yet initialized --- data/core/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/core/init.lua b/data/core/init.lua index ca9f2f85..5c7025b2 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -1162,7 +1162,9 @@ function core.custom_log(level, show, backtrace, fmt, ...) local text = string.format(fmt, ...) if show then local s = style.log[level] - core.status_view:show_message(s.icon, s.color, text) + if core.status_view then + core.status_view:show_message(s.icon, s.color, text) + end end local info = debug.getinfo(2, "Sl") From 68e9c4670e1df60a07619c947bf42365d35e1a2f Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 9 Jun 2023 15:31:59 +0200 Subject: [PATCH 077/148] Revert "core syntax: strip the path from filename on syntax.get (#1168)" (#1322) * Revert "core syntax: strip the path from filename on syntax.get (#1168)" This reverts commit af6c4bc152234e13f3e12819e361e1b92a387013. The previous behavior was correct and allowed access to the full path for path-dependant syntaxes. * Use `Doc.abs_filename` to obtain syntax when possible This allows matching full paths in language syntaxes, but we lose the possibility of matching the project root. --- data/core/doc/init.lua | 7 ++++++- data/core/syntax.lua | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index 74116fd5..572b2d78 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -44,7 +44,12 @@ end function Doc:reset_syntax() local header = self:get_text(1, 1, self:position_offset(1, 1, 128)) - local syn = syntax.get(self.filename or "", header) + local path = self.abs_filename + if not path and self.filename then + path = core.project_dir .. PATHSEP .. self.filename + end + if path then path = common.normalize_path(path) end + local syn = syntax.get(path or "", header) if self.syntax ~= syn then self.syntax = syn self.highlighter:soft_reset() diff --git a/data/core/syntax.lua b/data/core/syntax.lua index 6fe8984a..977983c1 100644 --- a/data/core/syntax.lua +++ b/data/core/syntax.lua @@ -44,7 +44,7 @@ local function find(string, field) end function syntax.get(filename, header) - return find(common.basename(filename), "files") + return find(filename, "files") or (header and find(header, "headers")) or plain_text_syntax end From f1f81c885173e148d252947b182aa7833da14be7 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 9 Jun 2023 15:34:34 +0200 Subject: [PATCH 078/148] Make `Doc:sanitize_position` return a more appropriate `col` (#1469) If `line` is out of range, return the `col` "closest" to the original values. --- data/core/doc/init.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index 572b2d78..bf5895fb 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -281,9 +281,13 @@ end -- End of cursor seciton. function Doc:sanitize_position(line, col) - line = common.clamp(line, 1, #self.lines) - col = common.clamp(col, 1, #self.lines[line]) - return line, col + local nlines = #self.lines + if line > nlines then + return nlines, #self.lines[nlines] + elseif line < 1 then + return 1, 1 + end + return line, common.clamp(col, 1, #self.lines[line]) end From 964b8fe29dcb5a44ee27835d4c580e980b0366fb Mon Sep 17 00:00:00 2001 From: Guldoman Date: Tue, 13 Jun 2023 22:45:43 +0200 Subject: [PATCH 079/148] Increase number of loadable glyphsets (#1524) This should be enough to load every unicode codepoint. --- src/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer.c b/src/renderer.c index 6d14ea44..e10dd916 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -17,7 +17,7 @@ #include "renwindow.h" #define MAX_GLYPHSET 256 -#define MAX_LOADABLE_GLYPHSETS 1024 +#define MAX_LOADABLE_GLYPHSETS 4096 #define SUBPIXEL_BITMAPS_CACHED 3 RenWindow window_renderer = {0}; From 2af308264053663faa72aeed3771c765c52b79a3 Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 16 Jun 2023 16:19:52 +0200 Subject: [PATCH 080/148] Attach command buffer to Renderer Window (#1472) --- src/api/renderer.c | 4 ++-- src/rencache.c | 49 ++++++++++++++++++++++------------------------ src/rencache.h | 4 ++-- src/renderer.c | 9 ++++----- src/renwindow.c | 6 ++++++ src/renwindow.h | 4 ++++ 6 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/api/renderer.c b/src/api/renderer.c index b619b586..901824fe 100644 --- a/src/api/renderer.c +++ b/src/api/renderer.c @@ -311,7 +311,7 @@ static int f_set_clip_rect(lua_State *L) { lua_Number w = luaL_checknumber(L, 3); lua_Number h = luaL_checknumber(L, 4); RenRect rect = rect_to_grid(x, y, w, h); - rencache_set_clip_rect(rect); + rencache_set_clip_rect(&window_renderer, rect); return 0; } @@ -323,7 +323,7 @@ static int f_draw_rect(lua_State *L) { lua_Number h = luaL_checknumber(L, 4); RenRect rect = rect_to_grid(x, y, w, h); RenColor color = checkcolor(L, 5, 255); - rencache_draw_rect(rect, color); + rencache_draw_rect(&window_renderer, rect, color); return 0; } diff --git a/src/rencache.c b/src/rencache.c index 52527969..d28ed543 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -65,10 +65,7 @@ static unsigned cells_buf2[CELLS_X * CELLS_Y]; static unsigned *cells_prev = cells_buf1; static unsigned *cells = cells_buf2; static RenRect rect_buf[CELLS_X * CELLS_Y / 2]; -size_t command_buf_size = 0; -uint8_t *command_buf = NULL; static bool resize_issue; -static int command_buf_idx; static RenRect screen_rect; static RenRect last_clip_rect; static bool show_debug; @@ -116,21 +113,21 @@ static RenRect merge_rects(RenRect a, RenRect b) { return (RenRect) { x1, y1, x2 - x1, y2 - y1 }; } -static bool expand_command_buffer() { - size_t new_size = command_buf_size * CMD_BUF_RESIZE_RATE; +static bool expand_command_buffer(RenWindow *window_renderer) { + size_t new_size = window_renderer->command_buf_size * CMD_BUF_RESIZE_RATE; if (new_size == 0) { new_size = CMD_BUF_INIT_SIZE; } - uint8_t *new_command_buf = realloc(command_buf, new_size); + uint8_t *new_command_buf = realloc(window_renderer->command_buf, new_size); if (!new_command_buf) { return false; } - command_buf_size = new_size; - command_buf = new_command_buf; + window_renderer->command_buf_size = new_size; + window_renderer->command_buf = new_command_buf; return true; } -static void* push_command(enum CommandType type, int size) { +static void* push_command(RenWindow *window_renderer, enum CommandType type, int size) { if (resize_issue) { // Don't push new commands as we had problems resizing the command buffer. // Let's wait for the next frame. @@ -139,17 +136,17 @@ static void* push_command(enum CommandType type, int size) { size_t alignment = alignof(max_align_t) - 1; size += COMMAND_BARE_SIZE; size = (size + alignment) & ~alignment; - int n = command_buf_idx + size; - while (n > command_buf_size) { - if (!expand_command_buffer()) { + int n = window_renderer->command_buf_idx + size; + while (n > window_renderer->command_buf_size) { + if (!expand_command_buffer(window_renderer)) { fprintf(stderr, "Warning: (" __FILE__ "): unable to resize command buffer (%zu)\n", - (size_t)(command_buf_size * CMD_BUF_RESIZE_RATE)); + (size_t)(window_renderer->command_buf_size * CMD_BUF_RESIZE_RATE)); resize_issue = true; return NULL; } } - Command *cmd = (Command*) (command_buf + command_buf_idx); - command_buf_idx = n; + Command *cmd = (Command*) (window_renderer->command_buf + window_renderer->command_buf_idx); + window_renderer->command_buf_idx = n; memset(cmd, 0, size); cmd->type = type; cmd->size = size; @@ -157,13 +154,13 @@ static void* push_command(enum CommandType type, int size) { } -static bool next_command(Command **prev) { +static bool next_command(RenWindow *window_renderer, Command **prev) { if (*prev == NULL) { - *prev = (Command*) command_buf; + *prev = (Command*) window_renderer->command_buf; } else { *prev = (Command*) (((char*) *prev) + (*prev)->size); } - return *prev != ((Command*) (command_buf + command_buf_idx)); + return *prev != ((Command*) (window_renderer->command_buf + window_renderer->command_buf_idx)); } @@ -172,8 +169,8 @@ void rencache_show_debug(bool enable) { } -void rencache_set_clip_rect(RenRect rect) { - SetClipCommand *cmd = push_command(SET_CLIP, sizeof(SetClipCommand)); +void rencache_set_clip_rect(RenWindow *window_renderer, RenRect rect) { + SetClipCommand *cmd = push_command(window_renderer, SET_CLIP, sizeof(SetClipCommand)); if (cmd) { cmd->rect = intersect_rects(rect, screen_rect); last_clip_rect = cmd->rect; @@ -181,11 +178,11 @@ void rencache_set_clip_rect(RenRect rect) { } -void rencache_draw_rect(RenRect rect, RenColor color) { +void rencache_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color) { if (rect.width == 0 || rect.height == 0 || !rects_overlap(last_clip_rect, rect)) { return; } - DrawRectCommand *cmd = push_command(DRAW_RECT, sizeof(DrawRectCommand)); + DrawRectCommand *cmd = push_command(window_renderer, DRAW_RECT, sizeof(DrawRectCommand)); if (cmd) { cmd->rect = rect; cmd->color = color; @@ -198,7 +195,7 @@ double rencache_draw_text(RenWindow *window_renderer, RenFont **fonts, const cha RenRect rect = { x, y, (int)width, ren_font_group_get_height(fonts) }; if (rects_overlap(last_clip_rect, rect)) { int sz = len + 1; - DrawTextCommand *cmd = push_command(DRAW_TEXT, sizeof(DrawTextCommand) + sz); + DrawTextCommand *cmd = push_command(window_renderer, DRAW_TEXT, sizeof(DrawTextCommand) + sz); if (cmd) { memcpy(cmd->text, text, sz); cmd->color = color; @@ -265,7 +262,7 @@ void rencache_end_frame(RenWindow *window_renderer) { /* update cells from commands */ Command *cmd = NULL; RenRect cr = screen_rect; - while (next_command(&cmd)) { + while (next_command(window_renderer, &cmd)) { /* cmd->command[0] should always be the Command rect */ if (cmd->type == SET_CLIP) { cr = cmd->command[0]; } RenRect r = intersect_rects(cmd->command[0], cr); @@ -308,7 +305,7 @@ void rencache_end_frame(RenWindow *window_renderer) { ren_set_clip_rect(window_renderer, r); cmd = NULL; - while (next_command(&cmd)) { + while (next_command(window_renderer, &cmd)) { SetClipCommand *ccmd = (SetClipCommand*)&cmd->command; DrawRectCommand *rcmd = (DrawRectCommand*)&cmd->command; DrawTextCommand *tcmd = (DrawTextCommand*)&cmd->command; @@ -341,6 +338,6 @@ void rencache_end_frame(RenWindow *window_renderer) { unsigned *tmp = cells; cells = cells_prev; cells_prev = tmp; - command_buf_idx = 0; + window_renderer->command_buf_idx = 0; } diff --git a/src/rencache.h b/src/rencache.h index 2453d808..03963485 100644 --- a/src/rencache.h +++ b/src/rencache.h @@ -6,8 +6,8 @@ #include "renderer.h" void rencache_show_debug(bool enable); -void rencache_set_clip_rect(RenRect rect); -void rencache_draw_rect(RenRect rect, RenColor color); +void rencache_set_clip_rect(RenWindow *window_renderer, RenRect rect); +void rencache_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color); double rencache_draw_text(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, double x, int y, RenColor color); void rencache_invalidate(void); void rencache_begin_frame(RenWindow *window_renderer); diff --git a/src/renderer.c b/src/renderer.c index e10dd916..7f2d74fa 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -506,13 +506,11 @@ void ren_draw_rect(RenSurface *rs, RenRect rect, RenColor color) { /*************** Window Management ****************/ void ren_free_window_resources(RenWindow *window_renderer) { - extern uint8_t *command_buf; - extern size_t command_buf_size; renwin_free(window_renderer); SDL_FreeSurface(draw_rect_surface); - free(command_buf); - command_buf = NULL; - command_buf_size = 0; + free(window_renderer->command_buf); + window_renderer->command_buf = NULL; + window_renderer->command_buf_size = 0; } // TODO remove global and return RenWindow* @@ -525,6 +523,7 @@ void ren_init(SDL_Window *win) { } window_renderer.window = win; renwin_init_surface(&window_renderer); + renwin_init_command_buf(&window_renderer); renwin_clip_to_surface(&window_renderer); draw_rect_surface = SDL_CreateRGBSurface(0, 1, 1, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); diff --git a/src/renwindow.c b/src/renwindow.c index ba671404..fe40d009 100644 --- a/src/renwindow.c +++ b/src/renwindow.c @@ -45,6 +45,12 @@ void renwin_init_surface(UNUSED RenWindow *ren) { #endif } +void renwin_init_command_buf(RenWindow *ren) { + ren->command_buf = NULL; + ren->command_buf_idx = 0; + ren->command_buf_size = 0; +} + static RenRect scaled_rect(const RenRect rect, const int scale) { return (RenRect) {rect.x * scale, rect.y * scale, rect.width * scale, rect.height * scale}; diff --git a/src/renwindow.h b/src/renwindow.h index 6b0b9eaa..a80586a0 100644 --- a/src/renwindow.h +++ b/src/renwindow.h @@ -3,6 +3,9 @@ struct RenWindow { SDL_Window *window; + uint8_t *command_buf; + size_t command_buf_idx; + size_t command_buf_size; #ifdef LITE_USE_SDL_RENDERER SDL_Renderer *renderer; SDL_Texture *texture; @@ -12,6 +15,7 @@ struct RenWindow { typedef struct RenWindow RenWindow; void renwin_init_surface(RenWindow *ren); +void renwin_init_command_buf(RenWindow *ren); void renwin_clip_to_surface(RenWindow *ren); void renwin_set_clip_rect(RenWindow *ren, RenRect rect); void renwin_resize_surface(RenWindow *ren); From bd53bc37181468bfc2f635a233f717a2d1092ba1 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Sun, 25 Jun 2023 04:09:27 +0200 Subject: [PATCH 081/148] comment typo in object.lua (#1541) --- data/core/object.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/core/object.lua b/data/core/object.lua index afd13cdf..d42f9dbc 100644 --- a/data/core/object.lua +++ b/data/core/object.lua @@ -47,7 +47,7 @@ function Object:__tostring() return "Object" end ----Methamethod to allow using the object call as a constructor. +---Metamethod to allow using the object call as a constructor. ---@return core.object function Object:__call(...) local obj = setmetatable({}, self) From b5617a3eef578cfb5773081f04892f068d621265 Mon Sep 17 00:00:00 2001 From: Luke aka SwissalpS Date: Wed, 28 Jun 2023 03:05:03 +0200 Subject: [PATCH 082/148] Fix #1538 log scrolls automatically (the real PR) (#1546) * fix #1538 log scrolls automatically adds: - when user scrolls, position is kept no matter how many new entries arrive - when user scrolls up to last entry, autoscroll is enabled again does not add buttons to jump up/down see #1538 * move scroll-test out of on_mouse_wheel * determine diff_index with loop * remove check at move_towards yoffset * use while loop instead of repeat loop * remove meaningless setter * remove stray var --- data/core/logview.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/data/core/logview.lua b/data/core/logview.lua index 15aec22e..0d102832 100644 --- a/data/core/logview.lua +++ b/data/core/logview.lua @@ -125,9 +125,19 @@ end function LogView:update() local item = core.log_items[#core.log_items] if self.last_item ~= item then + local lh = style.font:get_height() + style.padding.y + if 0 < self.scroll.to.y then + local index = #core.log_items + while index > 1 and self.last_item ~= core.log_items[index] do + index = index - 1 + end + local diff_index = #core.log_items - index + self.scroll.to.y = self.scroll.to.y + diff_index * lh + self.scroll.y = self.scroll.to.y + else + self.yoffset = -lh + end self.last_item = item - self.scroll.to.y = 0 - self.yoffset = -(style.font:get_height() + style.padding.y) end local expanding = self.expanding[1] From e9678cc1403cf088f550fb0e617ede82d7bff31f Mon Sep 17 00:00:00 2001 From: Guldoman Date: Mon, 3 Jul 2023 22:39:54 +0200 Subject: [PATCH 083/148] Skip checking `files` if no filename was provided to `syntax.get` --- data/core/doc/init.lua | 2 +- data/core/syntax.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index bf5895fb..086e9f3e 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -49,7 +49,7 @@ function Doc:reset_syntax() path = core.project_dir .. PATHSEP .. self.filename end if path then path = common.normalize_path(path) end - local syn = syntax.get(path or "", header) + local syn = syntax.get(path, header) if self.syntax ~= syn then self.syntax = syn self.highlighter:soft_reset() diff --git a/data/core/syntax.lua b/data/core/syntax.lua index 977983c1..9862fbdf 100644 --- a/data/core/syntax.lua +++ b/data/core/syntax.lua @@ -44,7 +44,7 @@ local function find(string, field) end function syntax.get(filename, header) - return find(filename, "files") + return (filename and find(filename, "files")) or (header and find(header, "headers")) or plain_text_syntax end From f7400c924e8c7799f3952f784ce9874a7d59f42d Mon Sep 17 00:00:00 2001 From: Guldoman Date: Tue, 4 Jul 2023 05:50:28 +0200 Subject: [PATCH 084/148] Allow setting custom glyphset size (#1542) * Properly set glyphset size * Rename `MAX_GLYPHSET` to `GLYPHSET_SIZE` * Use more appropriate types for font metrics --- src/renderer.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/renderer.c b/src/renderer.c index 7f2d74fa..f8ae6302 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -16,8 +16,9 @@ #include "renderer.h" #include "renwindow.h" -#define MAX_GLYPHSET 256 -#define MAX_LOADABLE_GLYPHSETS 4096 +#define MAX_UNICODE 0x100000 +#define GLYPHSET_SIZE 256 +#define MAX_LOADABLE_GLYPHSETS (MAX_UNICODE / GLYPHSET_SIZE) #define SUBPIXEL_BITMAPS_CACHED 3 RenWindow window_renderer = {0}; @@ -37,14 +38,14 @@ static void* check_alloc(void *ptr) { /************************* Fonts *************************/ typedef struct { - unsigned short x0, x1, y0, y1, loaded; - short bitmap_left, bitmap_top; + unsigned int x0, x1, y0, y1, loaded; + int bitmap_left, bitmap_top; float xadvance; } GlyphMetric; typedef struct { SDL_Surface* surface; - GlyphMetric metrics[MAX_GLYPHSET]; + GlyphMetric metrics[GLYPHSET_SIZE]; } GlyphSet; typedef struct RenFont { @@ -128,14 +129,14 @@ static void font_load_glyphset(RenFont* font, int idx) { for (int j = 0, pen_x = 0; j < bitmaps_cached; ++j) { GlyphSet* set = check_alloc(calloc(1, sizeof(GlyphSet))); font->sets[j][idx] = set; - for (int i = 0; i < MAX_GLYPHSET; ++i) { - int glyph_index = FT_Get_Char_Index(font->face, i + idx * MAX_GLYPHSET); + for (int i = 0; i < GLYPHSET_SIZE; ++i) { + int glyph_index = FT_Get_Char_Index(font->face, i + idx * GLYPHSET_SIZE); if (!glyph_index || FT_Load_Glyph(font->face, glyph_index, load_option | FT_LOAD_BITMAP_METRICS_ONLY) || font_set_style(&font->face->glyph->outline, j * (64 / SUBPIXEL_BITMAPS_CACHED), font->style) || FT_Render_Glyph(font->face->glyph, render_option)) { continue; } FT_GlyphSlot slot = font->face->glyph; - int glyph_width = slot->bitmap.width / byte_width; + unsigned int glyph_width = slot->bitmap.width / byte_width; if (font->antialiasing == FONT_ANTIALIASING_NONE) glyph_width *= 8; set->metrics[i] = (GlyphMetric){ pen_x, pen_x + glyph_width, 0, slot->bitmap.rows, true, slot->bitmap_left, slot->bitmap_top, (slot->advance.x + slot->lsb_delta - slot->rsb_delta) / 64.0f}; @@ -153,8 +154,8 @@ static void font_load_glyphset(RenFont* font, int idx) { continue; set->surface = check_alloc(SDL_CreateRGBSurface(0, pen_x, font->max_height, font->antialiasing == FONT_ANTIALIASING_SUBPIXEL ? 24 : 8, 0, 0, 0, 0)); uint8_t* pixels = set->surface->pixels; - for (int i = 0; i < MAX_GLYPHSET; ++i) { - int glyph_index = FT_Get_Char_Index(font->face, i + idx * MAX_GLYPHSET); + for (int i = 0; i < GLYPHSET_SIZE; ++i) { + int glyph_index = FT_Get_Char_Index(font->face, i + idx * GLYPHSET_SIZE); if (!glyph_index || FT_Load_Glyph(font->face, glyph_index, load_option)) continue; FT_GlyphSlot slot = font->face->glyph; @@ -178,7 +179,7 @@ static void font_load_glyphset(RenFont* font, int idx) { } static GlyphSet* font_get_glyphset(RenFont* font, unsigned int codepoint, int subpixel_idx) { - int idx = (codepoint >> 8) % MAX_LOADABLE_GLYPHSETS; + int idx = (codepoint / GLYPHSET_SIZE) % MAX_LOADABLE_GLYPHSETS; if (!font->sets[font->antialiasing == FONT_ANTIALIASING_SUBPIXEL ? subpixel_idx : 0][idx]) font_load_glyphset(font, idx); return font->sets[font->antialiasing == FONT_ANTIALIASING_SUBPIXEL ? subpixel_idx : 0][idx]; @@ -192,7 +193,7 @@ static RenFont* font_group_get_glyph(GlyphSet** set, GlyphMetric** metric, RenFo bitmap_index += SUBPIXEL_BITMAPS_CACHED; for (int i = 0; i < FONT_FALLBACK_MAX && fonts[i]; ++i) { *set = font_get_glyphset(fonts[i], codepoint, bitmap_index); - *metric = &(*set)->metrics[codepoint % 256]; + *metric = &(*set)->metrics[codepoint % GLYPHSET_SIZE]; if ((*metric)->loaded || codepoint < 0xFF) return fonts[i]; } @@ -323,14 +324,16 @@ void ren_font_free(RenFont* font) { } void ren_font_group_set_tab_size(RenFont **fonts, int n) { + unsigned int tab_index = '\t' % GLYPHSET_SIZE; for (int j = 0; j < FONT_FALLBACK_MAX && fonts[j]; ++j) { for (int i = 0; i < (fonts[j]->antialiasing == FONT_ANTIALIASING_SUBPIXEL ? SUBPIXEL_BITMAPS_CACHED : 1); ++i) - font_get_glyphset(fonts[j], '\t', i)->metrics['\t'].xadvance = fonts[j]->space_advance * n; + font_get_glyphset(fonts[j], '\t', i)->metrics[tab_index].xadvance = fonts[j]->space_advance * n; } } int ren_font_group_get_tab_size(RenFont **fonts) { - float advance = font_get_glyphset(fonts[0], '\t', 0)->metrics['\t'].xadvance; + unsigned int tab_index = '\t' % GLYPHSET_SIZE; + float advance = font_get_glyphset(fonts[0], '\t', 0)->metrics[tab_index].xadvance; if (fonts[0]->space_advance) { advance /= fonts[0]->space_advance; } From 7f84ed311bc1c405c4890c646888e5cf3b43db04 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sun, 9 Jul 2023 08:42:40 +0800 Subject: [PATCH 085/148] style(src/renderer): use FreeType header names (#1554) --- src/renderer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer.c b/src/renderer.c index f8ae6302..6d95beeb 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -4,9 +4,9 @@ #include #include #include -#include -#include #include FT_FREETYPE_H +#include FT_LCD_FILTER_H +#include FT_OUTLINE_H #ifdef _WIN32 #include From 553251834b24f686eb100ab988da26da95ce4efc Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Tue, 11 Jul 2023 09:45:36 +0800 Subject: [PATCH 086/148] feat(src/renderer): stream fonts with SDL_RWops on all platforms (#1555) * feat(src/renderer): stream fonts with SDL_RWops on all platforms This fixes #1529 where the font itself carries the font file, which gets copied around. This commit streams the file, so the file is not entirely in memory. * style(src/renderer): use standard C types * refactor(src/renderer): implement FT_Stream.close * fix(src/renderer): fix SDL_RWops double free --- src/renderer.c | 111 +++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 63 deletions(-) diff --git a/src/renderer.c b/src/renderer.c index 6d95beeb..d08565ea 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -7,6 +7,7 @@ #include FT_FREETYPE_H #include FT_LCD_FILTER_H #include FT_OUTLINE_H +#include FT_SYSTEM_H #ifdef _WIN32 #include @@ -50,6 +51,7 @@ typedef struct { typedef struct RenFont { FT_Face face; + FT_StreamRec stream; GlyphSet* sets[SUBPIXEL_BITMAPS_CACHED][MAX_LOADABLE_GLYPHSETS]; float size, space_advance, tab_advance; unsigned short max_height, baseline, height; @@ -57,10 +59,6 @@ typedef struct RenFont { ERenFontHinting hinting; unsigned char style; unsigned short underline_thickness; -#ifdef _WIN32 - unsigned char *file; - HANDLE file_handle; -#endif char path[]; } RenFont; @@ -215,54 +213,49 @@ static void font_clear_glyph_cache(RenFont* font) { } } +// based on https://github.com/libsdl-org/SDL_ttf/blob/2a094959055fba09f7deed6e1ffeb986188982ae/SDL_ttf.c#L1735 +static unsigned long font_file_read(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) { + uint64_t amount; + SDL_RWops *file = (SDL_RWops *) stream->descriptor.pointer; + SDL_RWseek(file, (int) offset, RW_SEEK_SET); + if (count == 0) + return 0; + amount = SDL_RWread(file, buffer, sizeof(char), count); + if (amount <= 0) + return 0; + return (unsigned long) amount; +} + +static void font_file_close(FT_Stream stream) { + if (stream && stream->descriptor.pointer) { + SDL_RWclose((SDL_RWops *) stream->descriptor.pointer); + stream->descriptor.pointer = NULL; + } +} + RenFont* ren_font_load(RenWindow *window_renderer, const char* path, float size, ERenFontAntialiasing antialiasing, ERenFontHinting hinting, unsigned char style) { + RenFont *font = NULL; FT_Face face = NULL; + + SDL_RWops *file = SDL_RWFromFile(path, "rb"); + if (!file) + goto rwops_failure; -#ifdef _WIN32 + int len = strlen(path); + font = check_alloc(calloc(1, sizeof(RenFont) + len + 1)); + font->stream.read = font_file_read; + font->stream.close = font_file_close; + font->stream.descriptor.pointer = file; + font->stream.pos = 0; + font->stream.size = (unsigned long) SDL_RWsize(file); - HANDLE file = INVALID_HANDLE_VALUE; - DWORD read; - int font_file_len = 0; - unsigned char *font_file = NULL; - wchar_t *wpath = NULL; - - if ((wpath = utfconv_utf8towc(path)) == NULL) - return NULL; - - if ((file = CreateFileW(wpath, - GENERIC_READ, - FILE_SHARE_READ, // or else we can't copy fonts - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL)) == INVALID_HANDLE_VALUE) + if (FT_Open_Face(library, &(FT_Open_Args){ .flags = FT_OPEN_STREAM, .stream = &font->stream }, 0, &face)) goto failure; - if ((font_file_len = GetFileSize(file, NULL)) == INVALID_FILE_SIZE) - goto failure; - - font_file = check_alloc(malloc(font_file_len * sizeof(unsigned char))); - if (!ReadFile(file, font_file, font_file_len, &read, NULL) || read != font_file_len) - goto failure; - - free(wpath); - wpath = NULL; - - if (FT_New_Memory_Face(library, font_file, read, 0, &face)) - goto failure; - -#else - - if (FT_New_Face(library, path, 0, &face)) - return NULL; - -#endif - const int surface_scale = renwin_get_surface(window_renderer).scale; if (FT_Set_Pixel_Sizes(face, 0, (int)(size*surface_scale))) goto failure; - int len = strlen(path); - RenFont* font = check_alloc(calloc(1, sizeof(RenFont) + len + 1)); + strcpy(font->path, path); font->face = face; font->size = size; @@ -272,32 +265,28 @@ RenFont* ren_font_load(RenWindow *window_renderer, const char* path, float size, font->hinting = hinting; font->style = style; -#ifdef _WIN32 - // we need to keep this for freetype - font->file = font_file; - font->file_handle = file; -#endif - if(FT_IS_SCALABLE(face)) font->underline_thickness = (unsigned short)((face->underline_thickness / (float)face->units_per_EM) * font->size); - if(!font->underline_thickness) font->underline_thickness = ceil((double) font->height / 14.0); + if(!font->underline_thickness) + font->underline_thickness = ceil((double) font->height / 14.0); - if (FT_Load_Char(face, ' ', font_set_load_options(font))) { - free(font); + if (FT_Load_Char(face, ' ', font_set_load_options(font))) goto failure; - } + font->space_advance = face->glyph->advance.x / 64.0f; font->tab_advance = font->space_advance * 2; return font; failure: -#ifdef _WIN32 - free(wpath); - free(font_file); - if (file != INVALID_HANDLE_VALUE) CloseHandle(file); -#endif - if (face != NULL) + if (face) FT_Done_Face(face); + if (font) + free(font); + return NULL; + +rwops_failure: + if (file) + SDL_RWclose(file); return NULL; } @@ -316,10 +305,6 @@ const char* ren_font_get_path(RenFont *font) { void ren_font_free(RenFont* font) { font_clear_glyph_cache(font); FT_Done_Face(font->face); -#ifdef _WIN32 - free(font->file); - CloseHandle(font->file_handle); -#endif free(font); } From ad0d280ecc2f854d508b1c67890f4e5147628619 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sun, 23 Jul 2023 03:39:32 +0800 Subject: [PATCH 087/148] Documentation for core.common (#1510) * docs(core.common): add and improve documentation * refactor(core.common): remove unused variable to get_height() * docs(core.common): remove messy newlines * docs(core.common): fix wording * docs(core.common): use integer instead of number Co-authored-by: Guldoman * docs(core.common): update docs the docs now follow the style in docs/ directory. some of the changes suggested are also implemented. * docs(core.common): fix typo Co-authored-by: Guldoman * docs(core.common): restyle annoatations Extra whitespaces are removed and @overload is used whenever possible. * docs(core.common): fix various documentation errors * docs(core.common): simplify unicode description * docs(core.common): fix return value Co-authored-by: Guldoman * docs(core.common): clarify common.bench for not being a benchmark * docs(common): add disclaimer for numbers in common.serialize --------- Co-authored-by: Guldoman --- data/core/common.lua | 221 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 205 insertions(+), 16 deletions(-) diff --git a/data/core/common.lua b/data/core/common.lua index b6c9db67..272f0d5d 100644 --- a/data/core/common.lua +++ b/data/core/common.lua @@ -1,22 +1,41 @@ local common = {} +---Checks if the byte at offset is a UTF-8 continuation byte. +--- +---UTF-8 encodes code points in 1 to 4 bytes. +---For a multi-byte sequence, each byte following the start byte is a continuation byte. +---@param s string +---@param offset? integer The offset of the string to start searching. Defaults to 1. +---@return boolean function common.is_utf8_cont(s, offset) local byte = s:byte(offset or 1) return byte >= 0x80 and byte < 0xc0 end +---Returns an iterator that yields a UTF-8 character on each iteration. +---@param text string +---@return fun(): string function common.utf8_chars(text) return text:gmatch("[\0-\x7f\xc2-\xf4][\x80-\xbf]*") end +---Clamps the number n between lo and hi. +---@param n number +---@param lo number +---@param hi number +---@return number function common.clamp(n, lo, hi) return math.max(math.min(n, hi), lo) end +---Returns a new table containing the contents of b merged into a. +---@param a table|nil +---@param b table? +---@return table function common.merge(a, b) a = type(a) == "table" and a or {} local t = {} @@ -32,11 +51,19 @@ function common.merge(a, b) end +---Returns the value of a number rounded to the nearest integer. +---@param n number +---@return number function common.round(n) return n >= 0 and math.floor(n + 0.5) or math.ceil(n - 0.5) end +---Returns the first index where a subtable in tbl has prop set. +---If none is found, nil is returned. +---@param tbl table +---@param prop any +---@return number|nil function common.find_index(tbl, prop) for i, o in ipairs(tbl) do if o[prop] then return i end @@ -44,6 +71,16 @@ function common.find_index(tbl, prop) end +---Returns a value between a and b on a linear scale, based on the +---interpolation point t. +--- +---If a and b are tables, a table containing the result for all the +---elements in a and b is returned. +---@param a number +---@param b number +---@param t number +---@return number +---@overload fun(a: table, b: table, t: number): table function common.lerp(a, b, t) if type(a) ~= "table" then return a + (b - a) * t @@ -56,11 +93,29 @@ function common.lerp(a, b, t) end +---Returns the euclidean distance between two points. +---@param x1 number +---@param y1 number +---@param x2 number +---@param y2 number +---@return number function common.distance(x1, y1, x2, y2) return math.sqrt(((x2-x1) ^ 2)+((y2-y1) ^ 2)) end +---Parses a CSS color string. +--- +---Only these formats are supported: +---* `rgb(r, g, b)` +---* `rgba(r, g, b, a)` +---* `#rrggbbaa` +---* `#rrggbb` +---@param str string +---@return number r +---@return number g +---@return number b +---@return number a function common.color(str) local r, g, b, a = str:match("^#(%x%x)(%x%x)(%x%x)(%x?%x?)$") if r then @@ -81,6 +136,12 @@ function common.color(str) end +---Splices a numerically indexed table. +---This function mutates the original table. +---@param t any[] +---@param at number Index at which to start splicing. +---@param remove number Number of elements to remove. +---@param insert? any[] A table containing elements to insert after splicing. function common.splice(t, at, remove, insert) assert(remove >= 0, "bad argument #3 to 'splice' (non-negative value expected)") insert = insert or {} @@ -110,6 +171,16 @@ local function fuzzy_match_items(items, needle, files) end +---Performs fuzzy matching. +--- +---If the haystack is a string, a score ranging from 0 to 1 is returned.
+---If the haystack is a table, a table containing the haystack sorted in ascending +---order of similarity is returned. +---@param haystack string +---@param needle string +---@param files boolean If true, the matching process will be performed in reverse to better match paths. +---@return number +---@overload fun(haystack: string[], needle: string, files: boolean): string[] function common.fuzzy_match(haystack, needle, files) if type(haystack) == "table" then return fuzzy_match_items(haystack, needle, files) @@ -118,6 +189,14 @@ function common.fuzzy_match(haystack, needle, files) end +---Performs fuzzy matching and returns recently used strings if needed. +--- +---If the needle is empty, then a list of recently used strings +---are added to the result, followed by strings from the haystack. +---@param haystack string[] +---@param recents string[] +---@param needle string +---@return string[] function common.fuzzy_match_with_recents(haystack, recents, needle) if needle == "" then local recents_ext = {} @@ -136,6 +215,13 @@ function common.fuzzy_match_with_recents(haystack, recents, needle) end +---Returns a list of paths that are relative to the input path. +--- +---If a root directory is specified, the function returns paths +---that are relative to the root directory. +---@param text string The input path. +---@param root? string The root directory. +---@return string[] function common.path_suggest(text, root) if root and root:sub(-1) ~= PATHSEP then root = root .. PATHSEP @@ -189,6 +275,9 @@ function common.path_suggest(text, root) end +---Returns a list of directories that are related to a path. +---@param text string The input path. +---@return string[] function common.dir_path_suggest(text) local path, name = text:match("^(.-)([^/\\]*)$") local files = system.list_dir(path == "" and "." or path) or {} @@ -204,6 +293,10 @@ function common.dir_path_suggest(text) end +---Filters a list of paths to find those that are related to the input path. +---@param text string The input path. +---@param dir_list string[] A list of paths to filter. +---@return string[] function common.dir_list_suggest(text, dir_list) local path, name = text:match("^(.-)([^/\\]*)$") local res = {} @@ -216,6 +309,15 @@ function common.dir_list_suggest(text, dir_list) end +---Matches a string against a list of patterns. +--- +---If a match was found, its start and end index is returned. +---Otherwise, false is returned. +---@param text string +---@param pattern string|string[] +---@param ... any Other options for string.find(). +---@return number|boolean start_index +---@return number|nil end_index function common.match_pattern(text, pattern, ...) if type(pattern) == "string" then return text:find(pattern, ...) @@ -228,8 +330,24 @@ function common.match_pattern(text, pattern, ...) end +---Draws text onto the window. +---The function returns the X and Y coordinates of the bottom-right +---corner of the text. +---@param font renderer.font +---@param color renderer.color +---@param text string +---@param align string +---| '"left"' # Align text to the left of the bounding box +---| '"right"' # Align text to the right of the bounding box +---| '"center"' # Center text in the bounding box +---@param x number +---@param y number +---@param w number +---@param h number +---@return number x_advance +---@return number y_advance function common.draw_text(font, color, text, align, x,y,w,h) - local tw, th = font:get_width(text), font:get_height(text) + local tw, th = font:get_width(text), font:get_height() if align == "center" then x = x + (w - tw) / 2 elseif align == "right" then @@ -240,6 +358,16 @@ function common.draw_text(font, color, text, align, x,y,w,h) end +---Prints the execution time of a function. +--- +---The execution time and percentage of frame time +---for the function is printed to standard output.
+---The frame rate is always assumed to be 60 FPS, thus +---a value of 100% would mean that the benchmark took +---1/60 of a second to execute. +---@param name string +---@param fn fun(...: any): any +---@return any # The result returned by the function function common.bench(name, fn, ...) local start = system.get_time() local res = fn(...) @@ -285,14 +413,28 @@ local function serialize(val, pretty, indent_str, escape, sort, limit, level) return tostring(val) end --- Serialize `val` into a parsable string. --- Available options --- * pretty: enable pretty printing --- * indent_str: indent to use (" " by default) --- * escape: use normal escape characters instead of the ones used by string.format("%q", ...) --- * sort: sort the keys inside tables --- * limit: limit how deep to serialize --- * initial_indent: the initial indentation level + +---@class common.serializeoptions +---@field pretty boolean Enables pretty printing. +---@field indent_str string The indentation character to use. Defaults to `" "`. +---@field escape boolean Uses normal escape characters ("\n") instead of decimal escape sequences ("\10"). +---@field limit number Limits the depth when serializing nested tables. Defaults to `math.huge`. +---@field sort boolean Sorts the output if it is a sortable table. +---@field initial_indent number The initial indentation level. Defaults to 0. + +---Serializes a value into a Lua string that is loadable with load(). +--- +---Only these basic types are supported: +---* nil +---* boolean +---* number (except very large numbers and special constants, e.g. `math.huge`, `inf` and `nan`) +---* integer +---* string +---* table +--- +---@param val any +---@param opts? common.serializeoptions +---@return string function common.serialize(val, opts) opts = opts or {} local indent_str = opts.indent_str or " " @@ -304,6 +446,9 @@ function common.serialize(val, opts) end +---Returns the last portion of a path. +---@param path string +---@return string function common.basename(path) -- a path should never end by / or \ except if it is '/' (unix root) or -- 'X:\' (windows drive) @@ -311,12 +456,18 @@ function common.basename(path) end --- can return nil if there is no directory part in the path +---Returns the directory name of a path. +---If the path doesn't have a directory, this function may return nil. +---@param path string +---@return string|nil function common.dirname(path) return path:match("(.+)[\\/][^\\/]+$") end +---Returns a path where the user's home directory is replaced by `"~"`. +---@param text string +---@return string function common.home_encode(text) if HOME and string.find(text, HOME, 1, true) == 1 then local dir_pos = #HOME + 1 @@ -330,6 +481,9 @@ function common.home_encode(text) end +---Returns a list of paths where the user's home directory is replaced by `"~"`. +---@param paths string[] A list of paths to encode +---@return string[] function common.home_encode_list(paths) local t = {} for i = 1, #paths do @@ -339,6 +493,10 @@ function common.home_encode_list(paths) end +---Expands the `"~"` prefix in a path into the user's home directory. +---This function is not guaranteed to return an absolute path. +---@param text string +---@return string function common.home_expand(text) return HOME and text:gsub("^~", HOME) or text end @@ -356,12 +514,13 @@ local function split_on_slash(s, sep_pattern) end --- The filename argument given to the function is supposed to --- come from system.absolute_path and as such should be an --- absolute path without . or .. elements. --- This function exists because on Windows the drive letter returned --- by system.absolute_path is sometimes with a lower case and sometimes --- with an upper case so we normalize to upper case. +---Normalizes the drive letter in a Windows path to uppercase. +---This function expects an absolute path, e.g. a path from `system.absolute_path`. +--- +---This function is needed because the path returned by `system.absolute_path` +---may contain drive letters in upper or lowercase. +---@param filename string|nil The input path. +---@return string|nil function common.normalize_volume(filename) if not filename then return end if PATHSEP == '\\' then @@ -374,6 +533,13 @@ function common.normalize_volume(filename) end +---Normalizes a path into the same format across platforms. +--- +---On Windows, all drive letters are converted to uppercase. +---UNC paths with drive letters are converted back to ordinary Windows paths. +---All path separators (`"/"`, `"\\"`) are converted to platform-specific ones. +---@param filename string|nil +---@return string|nil function common.normalize_path(filename) if not filename then return end local volume @@ -414,16 +580,27 @@ function common.normalize_path(filename) end +---Checks whether a path is absolute or relative. +---@param path string +---@return boolean function common.is_absolute_path(path) return path:sub(1, 1) == PATHSEP or path:match("^(%a):\\") end +---Checks whether a path belongs to a parent directory. +---@param filename string The path to check. +---@param path string The parent path. +---@return boolean function common.path_belongs_to(filename, path) return string.find(filename, path .. PATHSEP, 1, true) == 1 end +---Checks whether a path is relative to another path. +---@param ref_dir string The path to check against. +---@param dir string The input path. +---@return boolean function common.relative_path(ref_dir, dir) local drive_pattern = "^(%a):\\" local drive, ref_drive = dir:match(drive_pattern), ref_dir:match(drive_pattern) @@ -449,6 +626,11 @@ function common.relative_path(ref_dir, dir) end +---Creates a directory recursively if necessary. +---@param path string +---@return boolean success +---@return string|nil error +---@return string|nil path The path where an error occured. function common.mkdirp(path) local stat = system.get_file_info(path) if stat and stat.type then @@ -471,6 +653,13 @@ function common.mkdirp(path) return true end + +---Removes a path. +---@param path string +---@param recursively boolean If true, the function will attempt to remove everything in the specified path. +---@return boolean success +---@return string|nil error +---@return string|nil path The path where the error occured. function common.rm(path, recursively) local stat = system.get_file_info(path) if not stat or (stat.type ~= "file" and stat.type ~= "dir") then From b5b66823035f9cf652ddaa62eea2a299f3842302 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sun, 23 Jul 2023 19:17:45 +0800 Subject: [PATCH 088/148] docs(system): fix missing parameter for system.path_compare (#1566) * docs(system): fix missing parameter for system.path_compare * docs(system): fix missing parameter in function prototype --- docs/api/system.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/api/system.lua b/docs/api/system.lua index ffbc6f42..9e5ef289 100644 --- a/docs/api/system.lua +++ b/docs/api/system.lua @@ -318,9 +318,11 @@ function system.load_native_plugin(name, path) end ---Compares two paths in the order used by TreeView. --- ---@param path1 string +---@param type1 system.fileinfotype ---@param path2 string +---@param type2 system.fileinfotype ---@return boolean compare_result True if path1 < path2 -function system.path_compare(path1, path2) end +function system.path_compare(path1, type1, path2, type2) end return system From 5d0bcc99fa2462dc200b5f6f34b807fddcff7d58 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Thu, 27 Jul 2023 19:04:44 +0800 Subject: [PATCH 089/148] Documentation for core.command (#1564) * docs(core.command): add documentation * fix(core.common): fix warnings * docs(core.command): add "core." prefix to all custom types * docs(core.command); add name as parameter to command.perform * docs(core.command): fix typo and wording * docs(core.command): add disclaimer to command.generate_predicate * docs(core.command): fix wording for predicate * docs(core.command): document command name * docs(core.command): document the always_true predicate --- data/core/command.lua | 98 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 15 deletions(-) diff --git a/data/core/command.lua b/data/core/command.lua index faf872e2..2b28f63b 100644 --- a/data/core/command.lua +++ b/data/core/command.lua @@ -1,25 +1,55 @@ local core = require "core" local command = {} +---A predicate function accepts arguments from `command.perform()` and evaluates to a boolean.
+---If the function returns true, then the function associated with the command is executed. +--- +---The predicate function can also return other values after the boolean, which will +---be passed into the function associated with the command. +---@alias core.command.predicate_function fun(...: any): boolean, ... + +---A predicate is a string, an Object or a function, that is used to determine +---whether a command should be executed. +--- +---If the predicate is a string, it is resolved into an `Object` via `require()` +---and checked against the active view with `Object:extends()`.
+---For example, `"core.docview"` will match any view that inherits from `DocView`.
+---A `!` can be appended to the predicate to strictly match the current view via `Object:is()`, +---instead of matching any view that inherits the predicate. +--- +---If the predicate is a table, it is checked against the active view with `Object:extends()`. +---Strict matching via `Object:is()` is not available. +--- +---If the predicate is a function, it must behave like a predicate function. +---@see core.command.predicate_function +---@alias core.command.predicate string|core.object|core.command.predicate_function + +---A command is identified by a command name. +---The command name contains a category and the name itself, separated by a colon (':'). +--- +---All commands should be in lowercase and should not contain whitespaces; instead +---they should be replaced by a dash ('-'). +---@alias core.command.command_name string + +---The predicate and its associated function. +---@class core.command.command +---@field predicate core.command.predicate_function +---@field perform fun(...: any) + +---@type { [string]: core.command.command } command.map = {} +---@type core.command.predicate_function local always_true = function() return true end ----Used iternally by command.add, statusview, and contextmenu to generate a ----function with a condition to evaluate returning the boolean result of this ----evaluation. +---This function takes in a predicate and produces a predicate function +---that is internally used to dispatch and execute commands. --- ----If a string predicate is given it is treated as a require import that should ----return a valid object which is checked against the current active view, ----eg: "core.docview" will match any view that inherits from DocView. Appending ----a `!` at the end of the string means we want to match the given object ----from the import strcitly eg: "core.docview!" only DocView is matched. ----A function that returns a boolean can be used instead to perform a custom ----evaluation, setting to nil means always evaluates to true. ---- ----@param predicate string | table | function ----@return function +---This function should not be called manually. +---@see core.command.predicate +---@param predicate core.command.predicate|nil If nil, the predicate always evaluates to true. +---@return core.command.predicate_function function command.generate_predicate(predicate) predicate = predicate or always_true local strict = false @@ -38,10 +68,20 @@ function command.generate_predicate(predicate) predicate = function(...) return core.active_view:is(class), core.active_view, ... end end end + ---@cast predicate core.command.predicate_function return predicate end +---Adds commands to the map. +--- +---The function accepts a table containing a list of commands +---and their functions.
+---If a command already exists, it will be replaced. +---@see core.command.predicate +---@see core.command.command_name +---@param predicate core.command.predicate +---@param map { [core.command.command_name]: fun(...: any) } function command.add(predicate, map) predicate = command.generate_predicate(predicate) for name, fn in pairs(map) do @@ -57,11 +97,21 @@ local function capitalize_first(str) return str:sub(1, 1):upper() .. str:sub(2) end +---Prettifies the command name. +--- +---This function adds a space between the colon and the command name, +---replaces dashes with spaces and capitalizes the command appropriately. +---@see core.command.command_name +---@param name core.command.command_name +---@return string function command.prettify_name(name) + ---@diagnostic disable-next-line: redundant-return-value return name:gsub(":", ": "):gsub("-", " "):gsub("%S+", capitalize_first) end +---Returns all the commands that can be executed (their predicates evaluate to true). +---@return core.command.command_name[] function command.get_all_valid() local res = {} local memoized_predicates = {} @@ -76,6 +126,10 @@ function command.get_all_valid() return res end +---Checks whether a command can be executed (its predicate evaluates to true). +---@param name core.command.command_name +---@param ... any +---@return boolean function command.is_valid(name, ...) return command.map[name] and command.map[name].predicate(...) end @@ -98,12 +152,26 @@ local function perform(name, ...) end -function command.perform(...) - local ok, res = core.try(perform, ...) +---Performs a command. +--- +---The arguments passed into this function are forwarded to the predicate function.
+---If the predicate function returns more than 1 value, the other values are passed +---to the command. +--- +---Otherwise, the arguments passed into this function are passed directly +---to the command. +---@see core.command.predicate +---@see core.command.predicate_function +---@param name core.command.command_name +---@param ... any +---@return boolean # true if the command is performed successfully. +function command.perform(name, ...) + local ok, res = core.try(perform, name, ...) return not ok or res end +---Inserts the default commands for Lite XL into the map. function command.add_defaults() local reg = { "core", "root", "command", "doc", "findreplace", From 07818934b6e8710043b85e8e48d2df0e1e794598 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Fri, 4 Aug 2023 02:03:33 +0800 Subject: [PATCH 090/148] feat(src/renderer): unify fontgroup baseline (#1560) * feat(src/renderer): unify fontgroup baseline * fix(src/renderer): use the first font's baseline for the text run --- src/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer.c b/src/renderer.c index d08565ea..f4dbcc78 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -397,7 +397,7 @@ double ren_draw_text(RenSurface *rs, RenFont **fonts, const char *text, size_t l if (set->surface && color.a > 0 && end_x >= clip.x && start_x < clip_end_x) { uint8_t* source_pixels = set->surface->pixels; for (int line = metric->y0; line < metric->y1; ++line) { - int target_y = line + y - metric->bitmap_top + font->baseline * surface_scale; + int target_y = line + y - metric->bitmap_top + fonts[0]->baseline * surface_scale; if (target_y < clip.y) continue; if (target_y >= clip_end_y) From e62a672d7e8065c64cc7ef1d3b6eda296961c531 Mon Sep 17 00:00:00 2001 From: Delta-official Date: Fri, 4 Aug 2023 13:38:33 +0000 Subject: [PATCH 091/148] Normalize stroke before adding keybind (#1334) * Normalize stroke before adding keybind * improve normalization algorithm and implement normalization in several functions Signed-off-by: delta --------- Signed-off-by: delta --- data/core/keymap.lua | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/data/core/keymap.lua b/data/core/keymap.lua index 35e34e6a..70b7a3a9 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -35,6 +35,23 @@ local modkey_map = modkeys_os.map local modkeys = modkeys_os.keys +---Normalizes a stroke sequence to follow the modkeys table +---@param stroke string +---@return string +local function normalize_stroke(stroke) + local stroke_table = {} + for modkey in stroke:gmatch("(%w+)%+") do + table.insert(stroke_table, modkey) + end + if not next(stroke_table) then + return stroke + end + table.sort(stroke_table) + local new_stroke = table.concat(stroke_table, "+") .. "+" + return new_stroke .. stroke:sub(new_stroke:len() + 1) +end + + ---Generates a stroke sequence including currently pressed mod keys. ---@param key string ---@return string @@ -45,10 +62,9 @@ local function key_to_stroke(key) stroke = stroke .. mk .. "+" end end - return stroke .. key + return normalize_stroke(stroke) .. key end - ---Remove the given value from an array associated to a key in a table. ---@param tbl table The table containing the key ---@param k string The key containing the array @@ -74,6 +90,7 @@ end ---@param map keymap.map local function remove_duplicates(map) for stroke, commands in pairs(map) do + stroke = normalize_stroke(stroke) if type(commands) == "string" or type(commands) == "function" then commands = { commands } end @@ -96,11 +113,12 @@ local function remove_duplicates(map) end end - ---Add bindings by replacing commands that were previously assigned to a shortcut. ---@param map keymap.map function keymap.add_direct(map) for stroke, commands in pairs(map) do + stroke = normalize_stroke(stroke) + if type(commands) == "string" or type(commands) == "function" then commands = { commands } end @@ -128,6 +146,7 @@ function keymap.add(map, overwrite) if macos then stroke = stroke:gsub("%f[%a]ctrl%f[%A]", "cmd") end + stroke = normalize_stroke(stroke) if overwrite then if keymap.map[stroke] then for _, cmd in ipairs(keymap.map[stroke]) do @@ -153,7 +172,7 @@ end ---@param shortcut string ---@param cmd string function keymap.unbind(shortcut, cmd) - remove_only(keymap.map, shortcut, cmd) + remove_only(keymap.map, normalize_stroke(shortcut), cmd) remove_only(keymap.reverse_map, cmd, shortcut) end From 9120fb0046e22e750d80769e1078f321bc24c931 Mon Sep 17 00:00:00 2001 From: Shreyas A S <137637016+shreyas-a-s@users.noreply.github.com> Date: Fri, 4 Aug 2023 19:11:49 +0530 Subject: [PATCH 092/148] Updating the *Installing prebuild* section in README.md (#1548) Sub sections that I've updated: *To run lite-xl without installing:* *To install lite-xl copy files over into appropriate directories:* I think the directory structure of prebuilt packages has changed since when README.md was last updated. I've just updated it. Just that. Co-authored-by: Shreyas A S <137637016+shreyasastech@users.noreply.github.com> --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5d7e947b..ee318285 100644 --- a/README.md +++ b/README.md @@ -92,15 +92,14 @@ cd lite-xl To run lite-xl without installing: ```sh -cd bin ./lite-xl ``` To install lite-xl copy files over into appropriate directories: ```sh -mkdir -p $HOME/.local/bin && cp bin/lite-xl $HOME/.local/bin -cp -r share $HOME/.local +mkdir -p $HOME/.local/bin && cp lite-xl $HOME/.local/bin/ +mkdir -p $HOME/.local/share/lite-xl && cp -r data/* $HOME/.local/share/lite-xl/ ``` If `$HOME/.local/bin` is not in PATH: From c279ef0034f64ab9be678e0bf561d30ff6b9d21b Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Fri, 4 Aug 2023 09:46:35 -0400 Subject: [PATCH 093/148] Updated README.md as per PR comittee meeting #8. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ee318285..63bc45b9 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ To run lite-xl without installing: To install lite-xl copy files over into appropriate directories: ```sh +rm -rf $HOME/.local/share/lite-xl $HOME/.local/bin/lite-xl mkdir -p $HOME/.local/bin && cp lite-xl $HOME/.local/bin/ mkdir -p $HOME/.local/share/lite-xl && cp -r data/* $HOME/.local/share/lite-xl/ ``` From 86cfbe5f3b4e68f1d1b18f8494b73780337f48fa Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 4 Aug 2023 16:56:49 +0200 Subject: [PATCH 094/148] Make `DocView` aware of scrollbars sizes (#1177) * Make `DocView:scroll_to_make_visible` aware of vertical scrollbar width * Make `DocView` aware of horizontal scrollbar size --- data/core/docview.lua | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/data/core/docview.lua b/data/core/docview.lua index 908d7c6a..75a7b7b4 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -112,7 +112,8 @@ end function DocView:get_scrollable_size() if not config.scroll_past_end then - return self:get_line_height() * (#self.doc.lines) + style.padding.y * 2 + local _, _, _, h_scroll = self.h_scrollbar:get_track_rect() + return self:get_line_height() * (#self.doc.lines) + style.padding.y * 2 + h_scroll end return self:get_line_height() * (#self.doc.lines - 1) + self.size.y end @@ -244,7 +245,8 @@ function DocView:scroll_to_line(line, ignore_if_visible, instant) if not (ignore_if_visible and line > min and line < max) then local x, y = self:get_line_screen_position(line) local ox, oy = self:get_content_offset() - self.scroll.to.y = math.max(0, y - oy - self.size.y / 2) + local _, _, _, scroll_h = self.h_scrollbar:get_track_rect() + self.scroll.to.y = math.max(0, y - oy - (self.size.y - scroll_h) / 2) if instant then self.scroll.y = self.scroll.to.y end @@ -253,17 +255,20 @@ end function DocView:scroll_to_make_visible(line, col) - local ox, oy = self:get_content_offset() + local _, oy = self:get_content_offset() local _, ly = self:get_line_screen_position(line, col) local lh = self:get_line_height() - self.scroll.to.y = common.clamp(self.scroll.to.y, ly - oy - self.size.y + lh * 2, ly - oy - lh) + local _, _, _, scroll_h = self.h_scrollbar:get_track_rect() + self.scroll.to.y = common.clamp(self.scroll.to.y, ly - oy - self.size.y + scroll_h + lh * 2, ly - oy - lh) local gw = self:get_gutter_width() local xoffset = self:get_col_x_offset(line, col) local xmargin = 3 * self:get_font():get_width(' ') local xsup = xoffset + gw + xmargin local xinf = xoffset - xmargin - if xsup > self.scroll.x + self.size.x then - self.scroll.to.x = xsup - self.size.x + local _, _, scroll_w = self.v_scrollbar:get_track_rect() + local size_x = math.max(0, self.size.x - scroll_w) + if xsup > self.scroll.x + size_x then + self.scroll.to.x = xsup - size_x elseif xinf < self.scroll.x then self.scroll.to.x = math.max(0, xinf) end From eb27e543b4f60c81c38a9ac63c78aa5d57fe1e95 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sat, 5 Aug 2023 09:00:17 +0800 Subject: [PATCH 095/148] ci(release): use lite-xl org (#1571) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 581b6469..edf66372 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,7 @@ jobs: name: Linux needs: release runs-on: ubuntu-latest - container: ghcr.io/takase1121/lite-xl-build-box:latest + container: ghcr.io/lite-xl/lite-xl-build-box:latest env: CC: gcc CXX: g++ From 3d93e16597f6111943d7f6156e8b884f1d4a0e2f Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 25 Aug 2023 20:03:23 +0200 Subject: [PATCH 096/148] Normalize strokes in fixed order (#1572) * Use normalized strokes when removing duplicates only when appropriate * Use normalized stroke in `keymap.unbind` * Normalize strokes by sorting the modifiers before the keys This also sorts the modifiers in a fixed manner, decided by `modkeys.keys`. We need to do this because we display the strokes in a few places like the command palette. --- data/core/keymap.lua | 38 ++++++++++++++++++++--------------- data/core/modkeys-generic.lua | 2 +- data/core/modkeys-macos.lua | 2 +- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/data/core/keymap.lua b/data/core/keymap.lua index 70b7a3a9..ac6096b5 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -40,15 +40,19 @@ local modkeys = modkeys_os.keys ---@return string local function normalize_stroke(stroke) local stroke_table = {} - for modkey in stroke:gmatch("(%w+)%+") do - table.insert(stroke_table, modkey) + for key in stroke:gmatch("[^+]+") do + table.insert(stroke_table, key) end - if not next(stroke_table) then - return stroke - end - table.sort(stroke_table) - local new_stroke = table.concat(stroke_table, "+") .. "+" - return new_stroke .. stroke:sub(new_stroke:len() + 1) + table.sort(stroke_table, function(a, b) + if a == b then return false end + for _, mod in ipairs(modkeys) do + if a == mod or b == mod then + return a == mod + end + end + return a < b + end) + return table.concat(stroke_table, "+") end @@ -56,15 +60,16 @@ end ---@param key string ---@return string local function key_to_stroke(key) - local stroke = "" + local keys = { key } for _, mk in ipairs(modkeys) do if keymap.modkeys[mk] then - stroke = stroke .. mk .. "+" + table.insert(keys, mk) end end - return normalize_stroke(stroke) .. key + return normalize_stroke(table.concat(keys, "+")) end + ---Remove the given value from an array associated to a key in a table. ---@param tbl table The table containing the key ---@param k string The key containing the array @@ -90,12 +95,12 @@ end ---@param map keymap.map local function remove_duplicates(map) for stroke, commands in pairs(map) do - stroke = normalize_stroke(stroke) + local normalized_stroke = normalize_stroke(stroke) if type(commands) == "string" or type(commands) == "function" then commands = { commands } end - if keymap.map[stroke] then - for _, registered_cmd in ipairs(keymap.map[stroke]) do + if keymap.map[normalized_stroke] then + for _, registered_cmd in ipairs(keymap.map[normalized_stroke]) do local j = 0 for i=1, #commands do while commands[i + j] == registered_cmd do @@ -118,7 +123,7 @@ end function keymap.add_direct(map) for stroke, commands in pairs(map) do stroke = normalize_stroke(stroke) - + if type(commands) == "string" or type(commands) == "function" then commands = { commands } end @@ -172,7 +177,8 @@ end ---@param shortcut string ---@param cmd string function keymap.unbind(shortcut, cmd) - remove_only(keymap.map, normalize_stroke(shortcut), cmd) + shortcut = normalize_stroke(shortcut) + remove_only(keymap.map, shortcut, cmd) remove_only(keymap.reverse_map, cmd, shortcut) end diff --git a/data/core/modkeys-generic.lua b/data/core/modkeys-generic.lua index 6e264061..e239d8a9 100644 --- a/data/core/modkeys-generic.lua +++ b/data/core/modkeys-generic.lua @@ -9,6 +9,6 @@ modkeys.map = { ["right alt"] = "altgr", } -modkeys.keys = { "ctrl", "alt", "altgr", "shift" } +modkeys.keys = { "ctrl", "shift", "alt", "altgr" } return modkeys diff --git a/data/core/modkeys-macos.lua b/data/core/modkeys-macos.lua index e9fd0665..86b28de0 100644 --- a/data/core/modkeys-macos.lua +++ b/data/core/modkeys-macos.lua @@ -13,6 +13,6 @@ modkeys.map = { ["right alt"] = "altgr", } -modkeys.keys = { "cmd", "ctrl", "alt", "option", "altgr", "shift" } +modkeys.keys = { "ctrl", "alt", "option", "altgr", "shift", "cmd" } return modkeys From d937693ddb5b424afcd67e7cdf282bd8ac2074af Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 25 Aug 2023 04:33:39 +0200 Subject: [PATCH 097/148] Use Lua wrap by default (#1481) Debian and all its derivatives ship a broken Lua 5.4 that is missing some symbols. To work around broken distros and make development and distribution easier use the wrap by default and add an option to use the system version. --- meson.build | 37 ++++++++++++++++++++----------------- meson_options.txt | 3 ++- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/meson.build b/meson.build index cfef8ec8..5f7adcc4 100644 --- a/meson.build +++ b/meson.build @@ -4,8 +4,7 @@ project('lite-xl', license : 'MIT', meson_version : '>= 0.56', default_options : [ - 'c_std=gnu11', - 'wrap_mode=nofallback' + 'c_std=gnu11' ] ) @@ -84,23 +83,27 @@ if not get_option('source-only') 'lua', # Fedora ] - foreach lua : lua_names - last_lua = (lua == lua_names[-1] or get_option('wrap_mode') == 'forcefallback') - lua_dep = dependency(lua, fallback: last_lua ? ['lua', 'lua_dep'] : [], required : false, - version: '>= 5.4', + if get_option('use_system_lua') + foreach lua : lua_names + last_lua = (lua == lua_names[-1] or get_option('wrap_mode') == 'forcefallback') + lua_dep = dependency(lua, required : false, + ) + if lua_dep.found() + break + endif + + if last_lua + # If we could not find lua on the system and fallbacks are disabled + # try the compiler as a last ditch effort, since Lua has no official + # pkg-config support. + lua_dep = cc.find_library('lua', required : true) + endif + endforeach + else + lua_dep = dependency('', fallback: ['lua', 'lua_dep'], required : true, default_options: default_fallback_options + ['default_library=static', 'line_editing=false', 'interpreter=false'] ) - if lua_dep.found() - break - endif - - if last_lua - # If we could not find lua on the system and fallbacks are disabled - # try the compiler as a last ditch effort, since Lua has no official - # pkg-config support. - lua_dep = cc.find_library('lua', required : true) - endif - endforeach + endif pcre2_dep = dependency('libpcre2-8', fallback: ['pcre2', 'libpcre2_8'], default_options: default_fallback_options + ['default_library=static', 'grep=false', 'test=false'] diff --git a/meson_options.txt b/meson_options.txt index 9cfcc353..ae9d8c6b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,4 +3,5 @@ option('source-only', type : 'boolean', value : false, description: 'Configure s option('portable', type : 'boolean', value : false, description: 'Portable install') option('renderer', type : 'boolean', value : false, description: 'Use SDL renderer') option('dirmonitor_backend', type : 'combo', value : '', choices : ['', 'inotify', 'fsevents', 'kqueue', 'win32', 'dummy'], description: 'define what dirmonitor backend to use') -option('arch_tuple', type : 'string', value : '', description: 'Specify a custom architecture tuple') \ No newline at end of file +option('arch_tuple', type : 'string', value : '', description: 'Specify a custom architecture tuple') +option('use_system_lua', type : 'boolean', value : false, description: 'Prefer System Lua over a the meson wrap') From 09dd111c61dcea5a837873157a89e6ea0b92322b Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:32:07 +0800 Subject: [PATCH 098/148] docs(core.contextmenu): add documentation for contextmenu (#1567) --- data/core/contextmenu.lua | 56 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/data/core/contextmenu.lua b/data/core/contextmenu.lua index 4b466907..d59609d7 100644 --- a/data/core/contextmenu.lua +++ b/data/core/contextmenu.lua @@ -12,11 +12,31 @@ local divider_width = 1 local divider_padding = 5 local DIVIDER = {} +---An item in the context menu. +---@class core.contextmenu.item +---@field text string +---@field info string|nil If provided, this text is displayed on the right side of the menu. +---@field command string|fun() + +---A list of items with the same predicate. +---@see core.command.predicate +---@class core.contextmenu.itemset +---@field predicate core.command.predicate +---@field items core.contextmenu.item[] + +---A context menu. ---@class core.contextmenu : core.object +---@field itemset core.contextmenu.itemset[] +---@field show_context_menu boolean +---@field selected number +---@field position core.view.position +---@field current_scale number local ContextMenu = Object:extend() +---A unique value representing the divider in a context menu. ContextMenu.DIVIDER = DIVIDER +---Creates a new context menu. function ContextMenu:new() self.itemset = {} self.show_context_menu = false @@ -55,12 +75,19 @@ local function update_items_size(items, update_binding) items.width, items.height = width, height end +---Registers a list of items into the context menu with a predicate. +---@param predicate core.command.predicate +---@param items core.contextmenu.item[] function ContextMenu:register(predicate, items) predicate = command.generate_predicate(predicate) update_items_size(items, true) table.insert(self.itemset, { predicate = predicate, items = items }) end +---Shows the context menu. +---@param x number +---@param y number +---@return boolean # If true, the context menu is shown. function ContextMenu:show(x, y) self.items = nil local items_list = { width = 0, height = 0 } @@ -94,6 +121,7 @@ function ContextMenu:show(x, y) return false end +---Hides the context menu. function ContextMenu:hide() self.show_context_menu = false self.items = nil @@ -102,6 +130,8 @@ function ContextMenu:hide() core.request_cursor(core.active_view.cursor) end +---Returns an iterator that iterates over each context menu item and their dimensions. +---@return fun(): number, core.contextmenu.item, number, number, number, number function ContextMenu:each_item() local x, y, w = self.position.x, self.position.y, self.items.width local oy = y @@ -115,8 +145,12 @@ function ContextMenu:each_item() end) end +---Event handler for mouse movements. +---@param px any +---@param py any +---@return boolean # true if the event is caught. function ContextMenu:on_mouse_moved(px, py) - if not self.show_context_menu then return end + if not self.show_context_menu then return false end self.selected = -1 for i, item, x, y, w, h in self:each_item() do @@ -128,6 +162,8 @@ function ContextMenu:on_mouse_moved(px, py) return true end +---Event handler for when the selection is confirmed. +---@param item core.contextmenu.item function ContextMenu:on_selected(item) if type(item.command) == "string" then command.perform(item.command) @@ -140,6 +176,7 @@ local function change_value(value, change) return value + change end +---Selects the the previous item. function ContextMenu:focus_previous() self.selected = (self.selected == -1 or self.selected == 1) and #self.items or change_value(self.selected, -1) if self:get_item_selected() == DIVIDER then @@ -147,6 +184,7 @@ function ContextMenu:focus_previous() end end +---Selects the next item. function ContextMenu:focus_next() self.selected = (self.selected == -1 or self.selected == #self.items) and 1 or change_value(self.selected, 1) if self:get_item_selected() == DIVIDER then @@ -154,10 +192,13 @@ function ContextMenu:focus_next() end end +---Gets the currently selected item. +---@return core.contextmenu.item|nil function ContextMenu:get_item_selected() return (self.items or {})[self.selected] end +---Hides the context menu and performs the command if an item is selected. function ContextMenu:call_selected_item() local selected = self:get_item_selected() self:hide() @@ -166,6 +207,12 @@ function ContextMenu:call_selected_item() end end +---Event handler for mouse press. +---@param button core.view.mousebutton +---@param px number +---@param py number +---@param clicks number +---@return boolean # true if the event is caught. function ContextMenu:on_mouse_pressed(button, px, py, clicks) local caught = false @@ -186,14 +233,20 @@ function ContextMenu:on_mouse_pressed(button, px, py, clicks) return caught end +---@type fun(self: table, k: string, dest: number, rate?: number, name?: string) ContextMenu.move_towards = View.move_towards +---Event handler for content update. function ContextMenu:update() if self.show_context_menu then self:move_towards("height", self.items.height, nil, "contextmenu") end end +---Draws the context menu. +--- +---This wraps `ContextMenu:draw_context_menu()`. +---@see core.contextmenu.draw_context_menu function ContextMenu:draw() if not self.show_context_menu then return end if self.current_scale ~= SCALE then @@ -206,6 +259,7 @@ function ContextMenu:draw() core.root_view:defer_draw(self.draw_context_menu, self) end +---Draws the context menu. function ContextMenu:draw_context_menu() if not self.items then return end local bx, by, bw, bh = self.position.x, self.position.y, self.items.width, self.height From 890e4882f388aa362698fa39ccdec47049bc5152 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Fri, 18 Aug 2023 21:25:10 +0800 Subject: [PATCH 099/148] fix(core): defer core:open-log until everything is loaded (#1585) * fix(core): defer core:open-log until everything is loaded * docs(core): document why core:open-log is opened in a thread --- data/core/init.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/data/core/init.lua b/data/core/init.lua index 5c7025b2..dfd10388 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -808,7 +808,11 @@ function core.init() end if not plugins_success or got_user_error or got_project_error then - command.perform("core:open-log") + -- defer LogView to after everything is initialized, + -- so that EmptyView won't be added after LogView. + core.add_thread(function() + command.perform("core:open-log") + end) end core.configure_borderless_window() From 397b61e7c6cc185567bd816e453b3c88d1b843c7 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 23 Aug 2023 19:07:52 +0200 Subject: [PATCH 100/148] Fix returned `percent` when clicking the `Scrollbar` `track` --- data/core/scrollbar.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/core/scrollbar.lua b/data/core/scrollbar.lua index d2bb0562..5e64b19f 100644 --- a/data/core/scrollbar.lua +++ b/data/core/scrollbar.lua @@ -189,8 +189,9 @@ function Scrollbar:_on_mouse_pressed_normal(button, x, y, clicks) self.drag_start_offset = along - y return true elseif overlaps == "track" then + local nr = self.normal_rect self.drag_start_offset = - along_size / 2 - return (y - self.normal_rect.along - along_size / 2) / self.normal_rect.along_size + return common.clamp((y - nr.along - along_size / 2) / (nr.along_size - along_size), 0, 1) end end end From a9934c08d965fd025e12469979ee03a256a9d3be Mon Sep 17 00:00:00 2001 From: Robert Hildebrandt Date: Thu, 7 Sep 2023 01:54:52 +0200 Subject: [PATCH 101/148] Fixed C++14 digit separators (#1593) --- data/plugins/language_cpp.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/plugins/language_cpp.lua b/data/plugins/language_cpp.lua index a26ce868..70489713 100644 --- a/data/plugins/language_cpp.lua +++ b/data/plugins/language_cpp.lua @@ -14,9 +14,9 @@ syntax.add { { pattern = { "/%*", "%*/" }, type = "comment" }, { pattern = { '"', '"', '\\' }, type = "string" }, { pattern = { "'", "'", '\\' }, type = "string" }, - { pattern = "0x%x+", type = "number" }, + { pattern = "0x%x+[%x']*", type = "number" }, { pattern = "%d+[%d%.'eE]*f?", type = "number" }, - { pattern = "%.?%d+f?", type = "number" }, + { pattern = "%.?%d+[%d']*f?", type = "number" }, { pattern = "[%+%-=/%*%^%%<>!~|:&]", type = "operator" }, { pattern = "##", type = "operator" }, { pattern = "struct%s()[%a_][%w_]*", type = {"keyword", "keyword2"} }, From 784b911d41c855fbad1af1939b889fb5c0b10e6b Mon Sep 17 00:00:00 2001 From: Guldoman Date: Thu, 7 Sep 2023 04:07:21 +0200 Subject: [PATCH 102/148] Make `linewrapping` consider the expanded `Scrollbar` size This avoids reflowing the text when hovering the scrollbar. --- data/plugins/linewrapping.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/plugins/linewrapping.lua b/data/plugins/linewrapping.lua index 62412720..0b9f0b76 100644 --- a/data/plugins/linewrapping.lua +++ b/data/plugins/linewrapping.lua @@ -219,7 +219,7 @@ function LineWrapping.draw_guide(docview) end function LineWrapping.update_docview_breaks(docview) - local x,y,w,h = docview.v_scrollbar:get_thumb_rect() + local w = docview.v_scrollbar.expanded_size or style.expanded_scrollbar_size local width = (type(config.plugins.linewrapping.width_override) == "function" and config.plugins.linewrapping.width_override(docview)) or config.plugins.linewrapping.width_override or (docview.size.x - docview:get_gutter_width() - w) if (not docview.wrapped_settings or docview.wrapped_settings.width == nil or width ~= docview.wrapped_settings.width) then From 316fbbe7434cd5fcabf09b45481f5ccdafaacec9 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Sat, 30 Sep 2023 16:48:38 +0200 Subject: [PATCH 103/148] Remove DPI detection for default `SCALE` This often leads to `SCALE` values that are way off, and makes Lite XL unusable, so we now just default it to 1. --- data/core/start.lua | 2 +- src/main.c | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/data/core/start.lua b/data/core/start.lua index a0edbe54..040f109d 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -2,7 +2,7 @@ VERSION = "@PROJECT_VERSION@" MOD_VERSION = "3" -SCALE = tonumber(os.getenv("LITE_SCALE") or os.getenv("GDK_SCALE") or os.getenv("QT_SCALE_FACTOR")) or SCALE +SCALE = tonumber(os.getenv("LITE_SCALE") or os.getenv("GDK_SCALE") or os.getenv("QT_SCALE_FACTOR")) or 1 PATHSEP = package.config:sub(1, 1) EXEDIR = EXEFILE:match("^(.+)[/\\][^/\\]+$") diff --git a/src/main.c b/src/main.c index 468fb568..dca3cbd1 100644 --- a/src/main.c +++ b/src/main.c @@ -20,16 +20,6 @@ static SDL_Window *window; -static double get_scale(void) { -#ifndef __APPLE__ - float dpi; - if (SDL_GetDisplayDPI(0, NULL, &dpi, NULL) == 0) - return dpi / 96.0; -#endif - return 1.0; -} - - static void get_exe_filename(char *buf, int sz) { #if _WIN32 int len; @@ -203,9 +193,6 @@ init_lua: lua_pushstring(L, LITE_ARCH_TUPLE); lua_setglobal(L, "ARCH"); - lua_pushnumber(L, get_scale()); - lua_setglobal(L, "SCALE"); - char exename[2048]; get_exe_filename(exename, sizeof(exename)); if (*exename) { From 82589526c0a5628badbeb4c16f077a2518bdb304 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sun, 15 Oct 2023 04:16:36 +0800 Subject: [PATCH 104/148] fix: dim rendering when antialiasing is turned off (#1641) --- src/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer.c b/src/renderer.c index f4dbcc78..0e36aaa1 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -167,7 +167,7 @@ static void font_load_glyphset(RenFont* font, int idx) { for (unsigned int column = 0; column < slot->bitmap.width; ++column) { int current_source_offset = source_offset + (column / 8); int source_pixel = slot->bitmap.buffer[current_source_offset]; - pixels[++target_offset] = ((source_pixel >> (7 - (column % 8))) & 0x1) << 7; + pixels[++target_offset] = ((source_pixel >> (7 - (column % 8))) & 0x1) * 0xFF; } } else memcpy(&pixels[target_offset], &slot->bitmap.buffer[source_offset], slot->bitmap.width); From 1ad3b70e9ed927df1217d0e7eb2430ad830d9355 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 18 Oct 2023 06:45:31 +0200 Subject: [PATCH 105/148] Mark unsaved named files as dirty (#1598) --- data/core/doc/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index 086e9f3e..deeb3816 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -123,6 +123,7 @@ end function Doc:is_dirty() if self.new_file then + if self.filename then return true end return #self.lines > 1 or #self.lines[1] > 1 else return self.clean_change_id ~= self:get_change_id() From a066190ee25f06472f8d3f47a0004df7caf1f0af Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 18 Oct 2023 06:45:52 +0200 Subject: [PATCH 106/148] Improve `common.serialize` (#1640) * Make `common.serialize` more locale-independent * Handle inf/nan numbers in `common.serialize` --- data/core/common.lua | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/data/core/common.lua b/data/core/common.lua index 272f0d5d..a887c307 100644 --- a/data/core/common.lua +++ b/data/core/common.lua @@ -378,12 +378,15 @@ function common.bench(name, fn, ...) return res end +-- From gvx/Ser +local oddvals = {[tostring(1/0)] = "1/0", [tostring(-1/0)] = "-1/0", [tostring(-(0/0))] = "-(0/0)", [tostring(0/0)] = "0/0"} local function serialize(val, pretty, indent_str, escape, sort, limit, level) local space = pretty and " " or "" local indent = pretty and string.rep(indent_str, level) or "" local newline = pretty and "\n" or "" - if type(val) == "string" then + local ty = type(val) + if ty == "string" then local out = string.format("%q", val) if escape then out = string.gsub(out, "\\\n", "\\n") @@ -395,7 +398,7 @@ local function serialize(val, pretty, indent_str, escape, sort, limit, level) out = string.gsub(out, "\\13", "\\r") end return out - elseif type(val) == "table" then + elseif ty == "table" then -- early exit if level >= limit then return tostring(val) end local next_indent = pretty and (indent .. indent_str) or "" @@ -410,6 +413,12 @@ local function serialize(val, pretty, indent_str, escape, sort, limit, level) if sort then table.sort(t) end return "{" .. newline .. table.concat(t, "," .. newline) .. newline .. indent .. "}" end + if ty == "number" then + -- tostring is locale-dependent, so we need to replace an eventual `,` with `.` + local res, _ = tostring(val):gsub(",", ".") + -- handle inf/nan + return oddvals[res] or res + end return tostring(val) end From 8c451928bfdb1fd914f2e8fdee4236c02da9cfce Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 18 Oct 2023 06:46:27 +0200 Subject: [PATCH 107/148] Ignore keypresses during IME composition (#1573) Some IMEs continue sending keypresses even during composition, so we just ignore them. --- data/core/init.lua | 3 +++ data/core/keymap.lua | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index dfd10388..3f72619f 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -1243,6 +1243,9 @@ function core.on_event(type, ...) elseif type == "textediting" then ime.on_text_editing(...) elseif type == "keypressed" then + -- In some cases during IME composition input is still sent to us + -- so we just ignore it. + if ime.editing then return false end did_keymap = keymap.on_key_pressed(...) elseif type == "keyreleased" then keymap.on_key_released(...) diff --git a/data/core/keymap.lua b/data/core/keymap.lua index ac6096b5..7fce5a6b 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -203,10 +203,6 @@ end -- Events listening -------------------------------------------------------------------------------- function keymap.on_key_pressed(k, ...) - -- In MacOS and Windows during IME composition input is still sent to us - -- so we just ignore it - if PLATFORM ~= "Linux" and ime.editing then return false end - local mk = modkey_map[k] if mk then keymap.modkeys[mk] = true From 4005a4614452459d743fd3f54b082cdc2e9d50c4 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 18 Oct 2023 06:46:58 +0200 Subject: [PATCH 108/148] Save in the `workspace` unsaved named files and `crlf` status (#1597) * Save in the `workspace` unsaved named files * Save in the `workspace` the `crlf` status and restore it for "new" files --- data/plugins/workspace.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/data/plugins/workspace.lua b/data/plugins/workspace.lua index 6426cbdb..3b3bd044 100644 --- a/data/plugins/workspace.lua +++ b/data/plugins/workspace.lua @@ -83,7 +83,8 @@ local function save_view(view) filename = view.doc.filename, selection = { view.doc:get_selection() }, scroll = { x = view.scroll.to.x, y = view.scroll.to.y }, - text = not view.doc.filename and view.doc:get_text(1, 1, math.huge, math.huge) + crlf = view.doc.crlf, + text = view.doc.new_file and view.doc:get_text(1, 1, math.huge, math.huge) } end if mt == LogView then return end @@ -106,7 +107,6 @@ local function load_view(t) if not t.filename then -- document not associated to a file dv = DocView(core.open_doc()) - if t.text then dv.doc:insert(1, 1, t.text) end else -- we have a filename, try to read the file local ok, doc = pcall(core.open_doc, t.filename) @@ -114,9 +114,11 @@ local function load_view(t) dv = DocView(doc) end end - -- doc view "dv" can be nil here if the filename associated to the document - -- cannot be read. if dv and dv.doc then + if dv.doc.new_file and t.text then + dv.doc:insert(1, 1, t.text) + dv.doc.crlf = t.crlf + end dv.doc:set_selection(table.unpack(t.selection)) dv.last_line1, dv.last_col1, dv.last_line2, dv.last_col2 = dv.doc:get_selection() dv.scroll.x, dv.scroll.to.x = t.scroll.x, t.scroll.x From 5d53b13cf48c34287fed1c583e69f9d6f3266eaa Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sun, 22 Oct 2023 01:17:49 +0800 Subject: [PATCH 109/148] fix(dirmonitor): deadlock if error handler jumps somewhere else (#1647) * fix: deadlock if error handler jumps somewhere else * docs(dirmonitor): fix wrong data type in error callback * docs(dirmonitor): clarify coroutines and deadlocks * docs(dirmonitor): wording Co-authored-by: Guldoman --------- Co-authored-by: Guldoman --- data/core/dirwatch.lua | 4 ++++ docs/api/dirmonitor.lua | 6 +++++- src/api/dirmonitor.c | 22 +++++++++++++++++++--- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/data/core/dirwatch.lua b/data/core/dirwatch.lua index e3b6d61c..3b62fa24 100644 --- a/data/core/dirwatch.lua +++ b/data/core/dirwatch.lua @@ -91,6 +91,7 @@ end -- designed to be run inside a coroutine. function dirwatch:check(change_callback, scan_time, wait_time) local had_change = false + local last_error self.monitor:check(function(id) had_change = true if self.monitor:mode() == "single" then @@ -102,7 +103,10 @@ function dirwatch:check(change_callback, scan_time, wait_time) elseif self.reverse_watched[id] then change_callback(self.reverse_watched[id]) end + end, function(err) + last_error = err end) + if last_error ~= nil then error(last_error) end local start_time = system.get_time() for directory, old_modified in pairs(self.scanned) do if old_modified then diff --git a/docs/api/dirmonitor.lua b/docs/api/dirmonitor.lua index 439e0ec4..a12b61f1 100644 --- a/docs/api/dirmonitor.lua +++ b/docs/api/dirmonitor.lua @@ -45,10 +45,14 @@ function dirmonitor:unwatch(fd_or_path) end ---edited, removed or added. A file descriptor will be passed to the ---callback in "multiple" mode or a path in "single" mode. --- +---If an error occurred during the callback execution, the error callback will be called with the error object. +---This callback should not manipulate coroutines to avoid deadlocks. +--- ---@param callback dirmonitor.callback +---@param error_callback fun(error: any): nil --- ---@return boolean? changes True when changes were detected. -function dirmonitor:check(callback) end +function dirmonitor:check(callback, error_callback) end --- ---Get the working mode for the current file system monitoring backend. diff --git a/src/api/dirmonitor.c b/src/api/dirmonitor.c index 1bccfd13..320235a0 100644 --- a/src/api/dirmonitor.c +++ b/src/api/dirmonitor.c @@ -1,4 +1,5 @@ #include "api.h" +#include "lua.h" #include #include #include @@ -25,13 +26,16 @@ int get_mode_dirmonitor(); static int f_check_dir_callback(int watch_id, const char* path, void* L) { - lua_pushvalue(L, -1); + // using absolute indices from f_dirmonitor_check (2: callback, 3: error_callback) + lua_pushvalue(L, 2); if (path) lua_pushlstring(L, path, watch_id); else lua_pushnumber(L, watch_id); - lua_call(L, 1, 1); - int result = lua_toboolean(L, -1); + + int result = 0; + if (lua_pcall(L, 1, 1, 3) == LUA_OK) + result = lua_toboolean(L, -1); lua_pop(L, 1); return !result; } @@ -95,8 +99,20 @@ static int f_dirmonitor_unwatch(lua_State *L) { } +static int f_noop(lua_State *L) { return 0; } + + static int f_dirmonitor_check(lua_State* L) { struct dirmonitor* monitor = luaL_checkudata(L, 1, API_TYPE_DIRMONITOR); + luaL_checktype(L, 2, LUA_TFUNCTION); + if (!lua_isnoneornil(L, 3)) { + luaL_checktype(L, 3, LUA_TFUNCTION); + } else { + lua_settop(L, 2); + lua_pushcfunction(L, f_noop); + } + lua_settop(L, 3); + SDL_LockMutex(monitor->mutex); if (monitor->length < 0) lua_pushnil(L); From 63d99d4431bf9a691c3964e88c3f4e3574d526be Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Fri, 10 Nov 2023 09:36:44 +0800 Subject: [PATCH 110/148] feat(package): ad-hoc sign macOS bundles (#1656) * feat(package): ad-hoc sign macOS bundles * fix(package.sh): syntax error * docs(readme): add instructions for self-signed builds * docs(readme): grammar Co-authored-by: Guldoman --------- Co-authored-by: Guldoman --- README.md | 33 +++++++++++++++++++++++++++++++++ scripts/package.sh | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/README.md b/README.md index 63bc45b9..a4feaf7f 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,39 @@ affects only the place where the application is actually installed. Head over to [releases](https://github.com/lite-xl/lite-xl/releases) and download the version for your operating system. +### Windows + +Lite XL comes with installers on Windows for typical installations. +Alternatively, we provide ZIP archives that you can download and extract anywhere and run directly. + +To make Lite XL portable (e.g. running Lite XL from a thumb drive), +simply create a `user` folder where `lite-xl.exe` is located. +Lite XL will load and store all your configurations and plugins in the folder. + +### macOS + +We provide DMG files for macOS. Simply drag the program into your Applications folder. + +> **Important** +> Newer versions of Lite XL are signed with a self-signed certificate, +> so you'll have to follow these steps when running Lite XL for the first time. +> +> 1. Find Lite XL in Finder (do not open it in Launchpad). +> 2. Control-click Lite XL, then choose `Open` from the shortcut menu. +> 3. Click `Open` in the popup menu. +> +> The correct steps may vary between macOS versions, so you should refer to +> the [macOS User Guide](https://support.apple.com/en-my/guide/mac-help/mh40616/mac). +> +> On an older version of Lite XL, you will need to run these commands instead: +> +> ```sh +> # clears attributes from the directory +> xattr -cr /Applications/Lite\ XL.app +> ``` +> +> Otherwise, macOS will display a **very misleading error** saying that the application is damaged. + ### Linux Unzip the file and `cd` into the `lite-xl` directory: diff --git a/scripts/package.sh b/scripts/package.sh index d2346b76..1faba509 100644 --- a/scripts/package.sh +++ b/scripts/package.sh @@ -264,6 +264,11 @@ main() { $stripcmd "${exe_file}" fi + if [[ $bundle == true ]]; then + # https://eclecticlight.co/2019/01/17/code-signing-for-the-concerned-3-signing-an-app/ + codesign --force --deep -s - "${dest_dir}" + fi + echo "Creating a compressed archive ${package_name}" if [[ $binary == true ]]; then rm -f "${package_name}".tar.gz From 34d163aa25946744b7ef5225442759d085e43277 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Fri, 10 Nov 2023 09:44:58 +0800 Subject: [PATCH 111/148] refactor(build): use dmgbuild to create dmgs (#1664) * refactor(appdmg): make dmgs with dmgbuild * fix(appdmg.sh): typo * refactor(appdmg.sh): don't generate config on the fly * fix(dmgbuild): icon file * fix(gitignore): dmgbuild settings * chore(resources): update readme with new files * chore(resources/macos): add missing newline --- .github/workflows/build.yml | 8 +++-- .github/workflows/release.yml | 4 +-- .gitignore | 1 + build-packages.sh | 2 +- resources/README.md | 9 +++--- resources/macos/{appdmg.png => dmg-cover.png} | Bin resources/macos/lite-xl-dmg.py | 28 ++++++++++++++++++ scripts/README.md | 4 +-- scripts/appdmg.sh | 23 +------------- scripts/install-dependencies.sh | 4 +-- scripts/package.sh | 2 +- 11 files changed, 48 insertions(+), 37 deletions(-) rename resources/macos/{appdmg.png => dmg-cover.png} (100%) create mode 100644 resources/macos/lite-xl-dmg.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 398aae67..a1e2f01f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -110,6 +110,12 @@ jobs: run: | echo "$HOME/.local/bin" >> "$GITHUB_PATH" echo "INSTALL_NAME=lite-xl-${GITHUB_REF##*/}-macos-universal" >> "$GITHUB_ENV" + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + - name: Install dmgbuild + run: pip install dmgbuild - uses: actions/checkout@v3 - name: Download artifacts uses: actions/download-artifact@v3 @@ -117,8 +123,6 @@ jobs: with: name: macOS DMG Images path: dmgs-original - - name: Install appdmg - run: cd ~; npm i appdmg; cd - - name: Make universal bundles run: | bash --version diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index edf66372..5d9a388c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -185,8 +185,8 @@ jobs: uses: actions/setup-python@v2 with: python-version: 3.9 - - name: Install appdmg - run: cd ~; npm i appdmg; cd - + - name: Install dmgbuild + run: pip install dmgbuild - name: Prepare DMG Images run: | mkdir -p dmgs-addons dmgs-normal diff --git a/.gitignore b/.gitignore index 9b248455..7b420ff6 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ LiteXL* !resources/windows/*.diff !resources/windows/*.exe.manifest.in +!resources/macos/*.py diff --git a/build-packages.sh b/build-packages.sh index 96a7d11d..a95d3460 100755 --- a/build-packages.sh +++ b/build-packages.sh @@ -38,7 +38,7 @@ show_help() { echo "-v --version VERSION Sets the version on the package name." echo "-A --appimage Create an AppImage (Linux only)." echo "-D --dmg Create a DMG disk image (macOS only)." - echo " Requires NPM and AppDMG." + echo " Requires dmgbuild." echo "-I --innosetup Create an InnoSetup installer (Windows only)." echo "-r --release Compile in release mode." echo "-S --source Create a source code package," diff --git a/resources/README.md b/resources/README.md index cf30432c..d6d80eec 100644 --- a/resources/README.md +++ b/resources/README.md @@ -9,10 +9,11 @@ This folder contains resources that is used for building or packaging the projec ### Packaging - `icons/icon.{icns,ico,inl,rc,svg}`: lite-xl icon in various formats. -- `linux/org.lite_xl.lite_xl.appdata.xml`: AppStream metadata. -- `linux/org.lite_xl.lite_xl.desktop`: Desktop file for Linux desktops. -- `macos/appdmg.png`: Background image for packaging MacOS DMGs. -- `macos/Info.plist.in`: Template for generating `info.plist` on MacOS. See `macos/macos-retina-display.md` for details. +- `linux/com.lite_xl.LiteXL.appdata.xml`: AppStream metadata. +- `linux/com.lite_xl.LiteXL.desktop`: Desktop file for Linux desktops. +- `macos/dmg-cover.png`: Background image for packaging macOS DMGs. +- `macos/Info.plist.in`: Template for generating `info.plist` on macOS. See `macos/macos-retina-display.md` for details. +- `macos/lite-xl-dmg.py`: Configuration options for dmgbuild for packaging macOS DMGs. - `windows/001-lua-unicode.diff`: Patch for allowing Lua to load files with UTF-8 filenames on Windows. ### Development diff --git a/resources/macos/appdmg.png b/resources/macos/dmg-cover.png similarity index 100% rename from resources/macos/appdmg.png rename to resources/macos/dmg-cover.png diff --git a/resources/macos/lite-xl-dmg.py b/resources/macos/lite-xl-dmg.py new file mode 100644 index 00000000..27b24417 --- /dev/null +++ b/resources/macos/lite-xl-dmg.py @@ -0,0 +1,28 @@ +# configuration for dmgbuild + +import os.path + +app_path = "Lite XL.app" +app_name = os.path.basename(app_path) + +# Image options +format = defines.get("format", "UDZO") + +# Content options +files = [(app_path, app_name)] +symlinks = { "Applications": "/Applications" } +icon = "resources/icons/icon.icns" +icon_locations = { + app_name: (144, 248), + "Applications": (336, 248) +} + +# Window options +background = "resources/macos/dmg-cover.png" +window_rect = ((360, 360), (480, 380)) +default_view = "coverflow" +include_icon_view_settings = True + +# Icon view options +icon_size = 80 +text_size = 11.0 diff --git a/scripts/README.md b/scripts/README.md index 478e461f..5910931c 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -10,7 +10,7 @@ Various scripts and configurations used to configure, build, and package Lite XL ### Package -- **appdmg.sh**: Create a macOS DMG image using [AppDMG][1]. +- **appdmg.sh**: Create a macOS DMG image using [dmgbuild][1]. - **appimage.sh**: [AppImage][2] builder. - **innosetup.sh**: Creates a 32/64 bit [InnoSetup][3] installer package. - **package.sh**: Creates all binary / DMG image / installer / source packages. @@ -25,6 +25,6 @@ Various scripts and configurations used to configure, build, and package Lite XL - **generate_header.sh**: Generates a header file for native plugin API - **keymap-generator**: Generates a JSON file containing the keymap -[1]: https://github.com/LinusU/node-appdmg +[1]: https://github.com/dmgbuild/dmgbuild [2]: https://docs.appimage.org/ [3]: https://jrsoftware.org/isinfo.php diff --git a/scripts/appdmg.sh b/scripts/appdmg.sh index 840f518b..5ce4fe71 100644 --- a/scripts/appdmg.sh +++ b/scripts/appdmg.sh @@ -6,25 +6,4 @@ if [ ! -e "src/api/api.h" ]; then exit 1 fi -cat > lite-xl-dmg.json << EOF -{ - "title": "Lite XL", - "icon": "$(pwd)/resources/icons/icon.icns", - "background": "$(pwd)/resources/macos/appdmg.png", - "window": { - "position": { - "x": 360, - "y": 360 - }, - "size": { - "width": 480, - "height": 360 - } - }, - "contents": [ - { "x": 144, "y": 248, "type": "file", "path": "$(pwd)/Lite XL.app" }, - { "x": 336, "y": 248, "type": "link", "path": "/Applications" } - ] -} -EOF -~/node_modules/appdmg/bin/appdmg.js lite-xl-dmg.json "$(pwd)/$1.dmg" +dmgbuild -s resources/macos/lite-xl-dmg.py "Lite XL" "$1.dmg" diff --git a/scripts/install-dependencies.sh b/scripts/install-dependencies.sh index 1290cfcc..00606944 100644 --- a/scripts/install-dependencies.sh +++ b/scripts/install-dependencies.sh @@ -57,9 +57,7 @@ main() { else brew install bash ninja sdl2 fi - pip3 install meson - cd ~; npm install appdmg; cd - - ~/node_modules/appdmg/bin/appdmg.js --version + pip3 install meson dmgbuild elif [[ "$OSTYPE" == "msys" ]]; then if [[ $lhelper == true ]]; then pacman --noconfirm -S \ diff --git a/scripts/package.sh b/scripts/package.sh index 1faba509..d9a9c14c 100644 --- a/scripts/package.sh +++ b/scripts/package.sh @@ -25,7 +25,7 @@ show_help() { echo "-A --appimage Create an AppImage (Linux only)." echo "-B --binary Create a normal / portable package or macOS bundle," echo " depending on how the build was configured. (Default.)" - echo "-D --dmg Create a DMG disk image with AppDMG (macOS only)." + echo "-D --dmg Create a DMG disk image with dmgbuild (macOS only)." echo "-I --innosetup Create a InnoSetup package (Windows only)." echo "-r --release Strip debugging symbols." echo "-S --source Create a source code package," From fb7ed49a44217093f5dd9876b79989c567c639d8 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Tue, 28 Nov 2023 20:54:00 +0100 Subject: [PATCH 112/148] Avoid considering single spaces in `detectindent` (#1595) --- data/plugins/detectindent.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/plugins/detectindent.lua b/data/plugins/detectindent.lua index f2589ead..05070877 100644 --- a/data/plugins/detectindent.lua +++ b/data/plugins/detectindent.lua @@ -243,7 +243,7 @@ local function detect_indent_stat(doc) local max_lines = auto_detect_max_lines for i, text in get_non_empty_lines(doc.syntax, doc.lines) do local spaces = text:match("^ +") - if spaces then table.insert(stat, spaces:len()) end + if spaces and #spaces > 1 then table.insert(stat, #spaces) end local tabs = text:match("^\t+") if tabs then tab_count = tab_count + 1 end -- if nothing found for first lines try at least 4 more times From 01cab0611c1234591a6ed2843c4a79f06e91fd53 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Tue, 28 Nov 2023 20:54:11 +0100 Subject: [PATCH 113/148] Fix deleting indentation with multiple cursors (#1670) --- data/core/commands/doc.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index 0530f6e9..e840dbab 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -340,10 +340,11 @@ local commands = { local text = dv.doc:get_text(line1, 1, line1, col1) if #text >= indent_size and text:find("^ *$") then dv.doc:delete_to_cursor(idx, 0, -indent_size) - return + goto continue end end dv.doc:delete_to_cursor(idx, translate.previous_char) + ::continue:: end end, From 35ef0a94840c47aa657c60b1721ca0c88297c3c3 Mon Sep 17 00:00:00 2001 From: Daniel Margarido Date: Tue, 28 Nov 2023 23:34:44 +0000 Subject: [PATCH 114/148] Fixed issue with set_target_size passing the wrong value to plugins (#1657) * Fixed issue with set_target_size passing the wrong value to plugins that are split on the right and activated from the settings UI. * Added position awareness for the all resize_child_node calls. --- data/core/rootview.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/core/rootview.lua b/data/core/rootview.lua index 7230e8e1..047768cc 100644 --- a/data/core/rootview.lua +++ b/data/core/rootview.lua @@ -259,10 +259,10 @@ function RootView:on_mouse_moved(x, y, dx, dy) if self.dragged_divider then local node = self.dragged_divider if node.type == "hsplit" then - x = common.clamp(x, 0, self.root_node.size.x * 0.95) + x = common.clamp(x - node.position.x, 0, self.root_node.size.x * 0.95) resize_child_node(node, "x", x, dx) elseif node.type == "vsplit" then - y = common.clamp(y, 0, self.root_node.size.y * 0.95) + y = common.clamp(y - node.position.y, 0, self.root_node.size.y * 0.95) resize_child_node(node, "y", y, dy) end node.divider = common.clamp(node.divider, 0.01, 0.99) From 4adfd44d9f9882fd2b6a600607972bc50431b2b7 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 02:07:33 +0100 Subject: [PATCH 115/148] Limit `system.{sleep,wait_event}` to timeouts >= 0 (#1666) Otherwise we might wait forever by mistake. --- src/api/system.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/api/system.c b/src/api/system.c index 9e3fb5ab..1682f382 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -371,6 +371,7 @@ static int f_wait_event(lua_State *L) { int nargs = lua_gettop(L); if (nargs >= 1) { double n = luaL_checknumber(L, 1); + if (n < 0) n = 0; lua_pushboolean(L, SDL_WaitEventTimeout(NULL, n * 1000)); } else { lua_pushboolean(L, SDL_WaitEvent(NULL)); @@ -846,6 +847,7 @@ static int f_get_time(lua_State *L) { static int f_sleep(lua_State *L) { double n = luaL_checknumber(L, 1); + if (n < 0) n = 0; SDL_Delay(n * 1000); return 0; } From 3bf3266ca565e82113e49b0818fe9ae584fa96a7 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 28 Mar 2023 12:57:47 -0400 Subject: [PATCH 116/148] Made coroutines make more sense, and fixed a bug. (#1381) * Made coroutines make more sense, and fixed a bug. * Fixed typo. * Additional checking for off-cycles. * Fixed issue with calling step too much. * If we have no redraw, set next step time for next frame. * Added in `now` variables to reduce calls. --- data/core/init.lua | 58 ++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index 3f72619f..d12ef80d 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -305,7 +305,7 @@ function core.add_project_directory(path) end end if project_dir_open then - coroutine.yield(changed and 0.05 or 0) + coroutine.yield(changed and 0 or 0.05) else return end @@ -1356,7 +1356,7 @@ end local run_threads = coroutine.wrap(function() while true do local max_time = 1 / config.fps - 0.004 - local need_more_work = false + local minimal_time_to_wake = math.huge for k, thread in pairs(core.threads) do -- run thread @@ -1370,48 +1370,60 @@ local run_threads = coroutine.wrap(function() end elseif wait then thread.wake = system.get_time() + wait + minimal_time_to_wake = math.min(minimal_time_to_wake, wait) else - need_more_work = true + minimal_time_to_wake = 0 end + else + minimal_time_to_wake = math.min(minimal_time_to_wake, thread.wake - system.get_time()) end -- stop running threads if we're about to hit the end of frame if system.get_time() - core.frame_start > max_time then - coroutine.yield(true) + coroutine.yield(0) end end - if not need_more_work then coroutine.yield(false) end + coroutine.yield(minimal_time_to_wake) end end) function core.run() - local idle_iterations = 0 + local next_step while true do core.frame_start = system.get_time() - local need_more_work = run_threads() - local did_redraw = core.step() + local time_to_wake = run_threads() + local did_redraw = false + if not next_step or system.get_time() >= next_step then + did_redraw = core.step() + next_step = nil + end if core.restart_request or core.quit_request then break end - if not did_redraw and not need_more_work then - idle_iterations = idle_iterations + 1 - -- do not wait of events at idle_iterations = 1 to give a chance at core.step to run - -- and set "redraw" flag. - if idle_iterations > 1 then - if system.window_has_focus() then - -- keep running even with no events to make the cursor blinks - local t = system.get_time() - core.blink_start + + if not did_redraw then + if system.window_has_focus() then + local now = system.get_time() + if not next_step then -- compute the time until the next blink + local t = now - core.blink_start local h = config.blink_period / 2 local dt = math.ceil(t / h) * h - t - system.wait_event(dt + 1 / config.fps) - else - system.wait_event() + local cursor_time_to_wake = dt + 1 / config.fps + next_step = now + cursor_time_to_wake end + if time_to_wake > 0 and system.wait_event(math.min(next_step - now, time_to_wake)) then + next_step = nil -- if we've recevied an event, perform a step + end + else + system.wait_event() + next_step = nil -- perform a step when we're not in focus if get we an event end - else - idle_iterations = 0 - local elapsed = system.get_time() - core.frame_start - system.sleep(math.max(0, 1 / config.fps - elapsed)) + else -- if we redrew, then make sure we only draw at most FPS/sec + local now = system.get_time() + local elapsed = now - core.frame_start + local next_frame = math.max(0, 1 / config.fps - elapsed) + next_step = next_step or (now + next_frame) + system.sleep(math.min(next_frame, time_to_wake)) end end end From 6cd1f962340d64aa6a0518a6cd49f7210c2deb8d Mon Sep 17 00:00:00 2001 From: Guldoman Date: Sun, 12 Nov 2023 00:48:34 +0100 Subject: [PATCH 117/148] Fix running `core.step` when receiving an event while not waiting When `time_to_wake` was <= 0, so when a coroutine needed to be executed as soon as possible, we didn't check for events, so we only performed a `core.step` with the blink timer. This resulted in jerky reactions to input. --- data/core/init.lua | 2 +- docs/api/system.lua | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index d12ef80d..05805869 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -1411,7 +1411,7 @@ function core.run() local cursor_time_to_wake = dt + 1 / config.fps next_step = now + cursor_time_to_wake end - if time_to_wake > 0 and system.wait_event(math.min(next_step - now, time_to_wake)) then + if system.wait_event(math.min(next_step - now, time_to_wake)) then next_step = nil -- if we've recevied an event, perform a step end else diff --git a/docs/api/system.lua b/docs/api/system.lua index 9e5ef289..ae0f7424 100644 --- a/docs/api/system.lua +++ b/docs/api/system.lua @@ -61,10 +61,10 @@ function system.poll_event() end --- ---Wait until an event is triggered. --- ----@param timeout number Amount of seconds, also supports fractions ----of a second, eg: 0.01 +---@param timeout? number Amount of seconds, also supports fractions +---of a second, eg: 0.01. If not provided, waits forever. --- ----@return boolean status True on success or false if there was an error. +---@return boolean status True on success or false if there was an error or if no event was received. function system.wait_event(timeout) end --- From 5c5c77219b88286bb171bc54a03af2a3dd97f799 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 15:55:38 +0100 Subject: [PATCH 118/148] Fix `dirmonitor` sorting issues (#1599) * Use `PATHSEP` in path-related functions * Don't stop on digits when getting the common part in `system.path_compare` * Avoid sorting multiple times in `dirwatch.get_directory_files` This also fixes the timeout detection in `recurse_pred`. --- data/core/common.lua | 16 ++++++------- data/core/dirwatch.lua | 48 +++++++++++++++++++-------------------- data/core/init.lua | 10 ++++---- data/plugins/treeview.lua | 2 +- src/api/system.c | 3 +-- 5 files changed, 37 insertions(+), 42 deletions(-) diff --git a/data/core/common.lua b/data/core/common.lua index a887c307..82f1ab6f 100644 --- a/data/core/common.lua +++ b/data/core/common.lua @@ -226,7 +226,7 @@ function common.path_suggest(text, root) if root and root:sub(-1) ~= PATHSEP then root = root .. PATHSEP end - local path, name = text:match("^(.-)([^/\\]*)$") + local path, name = text:match("^(.-)([^"..PATHSEP.."]*)$") local clean_dotslash = false -- ignore root if path is absolute local is_absolute = common.is_absolute_path(text) @@ -279,7 +279,7 @@ end ---@param text string The input path. ---@return string[] function common.dir_path_suggest(text) - local path, name = text:match("^(.-)([^/\\]*)$") + local path, name = text:match("^(.-)([^"..PATHSEP.."]*)$") local files = system.list_dir(path == "" and "." or path) or {} local res = {} for _, file in ipairs(files) do @@ -298,7 +298,7 @@ end ---@param dir_list string[] A list of paths to filter. ---@return string[] function common.dir_list_suggest(text, dir_list) - local path, name = text:match("^(.-)([^/\\]*)$") + local path, name = text:match("^(.-)([^"..PATHSEP.."]*)$") local res = {} for _, dir_path in ipairs(dir_list) do if dir_path:lower():find(text:lower(), nil, true) == 1 then @@ -461,7 +461,7 @@ end function common.basename(path) -- a path should never end by / or \ except if it is '/' (unix root) or -- 'X:\' (windows drive) - return path:match("[^\\/]+$") or path + return path:match("[^"..PATHSEP.."]+$") or path end @@ -470,7 +470,7 @@ end ---@param path string ---@return string|nil function common.dirname(path) - return path:match("(.+)[\\/][^\\/]+$") + return path:match("(.+)["..PATHSEP.."][^"..PATHSEP.."]+$") end @@ -513,10 +513,10 @@ end local function split_on_slash(s, sep_pattern) local t = {} - if s:match("^[/\\]") then + if s:match("^["..PATHSEP.."]") then t[#t + 1] = "" end - for fragment in string.gmatch(s, "([^/\\]+)") do + for fragment in string.gmatch(s, "([^"..PATHSEP.."]+)") do t[#t + 1] = fragment end return t @@ -649,7 +649,7 @@ function common.mkdirp(path) while path and path ~= "" do local success_mkdir = system.mkdir(path) if success_mkdir then break end - local updir, basedir = path:match("(.*)[/\\](.+)$") + local updir, basedir = path:match("(.*)["..PATHSEP.."](.+)$") table.insert(subdirs, 1, basedir or path) path = updir end diff --git a/data/core/dirwatch.lua b/data/core/dirwatch.lua index 3b62fa24..d9ac4523 100644 --- a/data/core/dirwatch.lua +++ b/data/core/dirwatch.lua @@ -190,49 +190,47 @@ end -- "root" will by an absolute path without trailing '/' -- "path" will be a path starting without '/' and without trailing '/' -- or the empty string. --- It will identifies a sub-path within "root. +-- It identifies a sub-path within "root". -- The current path location will therefore always be: root .. path. --- When recursing "root" will always be the same, only "path" will change. +-- When recursing, "root" will always be the same, only "path" will change. -- Returns a list of file "items". In each item the "filename" will be the -- complete file path relative to "root" *without* the trailing '/', and without the starting '/'. -function dirwatch.get_directory_files(dir, root, path, t, entries_count, recurse_pred) +function dirwatch.get_directory_files(dir, root, path, entries_count, recurse_pred) + local t = {} local t0 = system.get_time() - local t_elapsed = system.get_time() - t0 - local dirs, files = {}, {} local ignore_compiled = compile_ignore_files() - local all = system.list_dir(root .. PATHSEP .. path) if not all then return nil end - - for _, file in ipairs(all or {}) do + local entries = { } + for _, file in ipairs(all) do local info = get_project_file_info(root, (path ~= "" and (path .. PATHSEP) or "") .. file, ignore_compiled) if info then - table.insert(info.type == "dir" and dirs or files, info) - entries_count = entries_count + 1 + table.insert(entries, info) end end + table.sort(entries, compare_file) local recurse_complete = true - table.sort(dirs, compare_file) - for _, f in ipairs(dirs) do - table.insert(t, f) - if recurse_pred(dir, f.filename, entries_count, t_elapsed) then - local _, complete, n = dirwatch.get_directory_files(dir, root, f.filename, t, entries_count, recurse_pred) - recurse_complete = recurse_complete and complete - if n ~= nil then - entries_count = n + for _, info in ipairs(entries) do + table.insert(t, info) + entries_count = entries_count + 1 + if info.type == "dir" then + if recurse_pred(dir, info.filename, entries_count, system.get_time() - t0) then + local t_rec, complete, n = dirwatch.get_directory_files(dir, root, info.filename, entries_count, recurse_pred) + recurse_complete = recurse_complete and complete + if n ~= nil then + entries_count = n + for _, info_rec in ipairs(t_rec) do + table.insert(t, info_rec) + end + end + else + recurse_complete = false end - else - recurse_complete = false end end - table.sort(files, compare_file) - for _, f in ipairs(files) do - table.insert(t, f) - end - return t, recurse_complete, entries_count end diff --git a/data/core/init.lua b/data/core/init.lua index 05805869..3f0cc096 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -102,7 +102,7 @@ local function strip_leading_path(filename) end local function strip_trailing_slash(filename) - if filename:match("[^:][/\\]$") then + if filename:match("[^:]["..PATHSEP.."]$") then return filename:sub(1, -2) end return filename @@ -120,9 +120,7 @@ local function show_max_files_warning(dir) "Too many files in project directory: stopped reading at ".. config.max_project_files.." files. For more information see ".. "usage.md at https://github.com/lite-xl/lite-xl." - if core.status_view then - core.status_view:show_message("!", style.accent, message) - end + core.warn(message) end @@ -184,7 +182,7 @@ local function refresh_directory(topdir, target) directory_start_idx = directory_start_idx + 1 end - local files = dirwatch.get_directory_files(topdir, topdir.name, (target or ""), {}, 0, function() return false end) + local files = dirwatch.get_directory_files(topdir, topdir.name, (target or ""), 0, function() return false end) local change = false -- If this file doesn't exist, we should be calling this on our parent directory, assume we'll do that. @@ -265,7 +263,7 @@ function core.add_project_directory(path) local fstype = PLATFORM == "Linux" and system.get_fs_type(topdir.name) or "unknown" topdir.force_scans = (fstype == "nfs" or fstype == "fuse") - local t, complete, entries_count = dirwatch.get_directory_files(topdir, topdir.name, "", {}, 0, timed_max_files_pred) + local t, complete, entries_count = dirwatch.get_directory_files(topdir, topdir.name, "", 0, timed_max_files_pred) topdir.files = t if not complete then topdir.slow_filesystem = not complete and (entries_count <= config.max_project_files) diff --git a/data/plugins/treeview.lua b/data/plugins/treeview.lua index e529cae1..f1dd6310 100644 --- a/data/plugins/treeview.lua +++ b/data/plugins/treeview.lua @@ -24,7 +24,7 @@ local tooltip_alpha_rate = 1 local function get_depth(filename) local n = 1 - for sep in filename:gmatch("[\\/]") do + for _ in filename:gmatch(PATHSEP) do n = n + 1 end return n diff --git a/src/api/system.c b/src/api/system.c index 1682f382..f7e0cf52 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -1043,7 +1043,7 @@ static int f_load_native_plugin(lua_State *L) { #endif /* Special purpose filepath compare function. Corresponds to the - order used in the TreeView view of the project's files. Returns true iff + order used in the TreeView view of the project's files. Returns true if path1 < path2 in the TreeView order. */ static int f_path_compare(lua_State *L) { size_t len1, len2; @@ -1057,7 +1057,6 @@ static int f_path_compare(lua_State *L) { size_t offset = 0, i, j; for (i = 0; i < len1 && i < len2; i++) { if (path1[i] != path2[i]) break; - if (isdigit(path1[i])) break; if (path1[i] == PATHSEP) { offset = i + 1; } From 43643a16c0ceec879b09e53967c11e5daedbb82d Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:46:56 +0800 Subject: [PATCH 119/148] fix(ci,build.sh): un-hardcode lua subproject detection --- .github/workflows/build.yml | 11 ++++++----- scripts/build.sh | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a1e2f01f..21f3a8b4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -204,13 +204,14 @@ jobs: run: | "INSTALL_NAME=lite-xl-$($env:GITHUB_REF -replace ".*/")-windows-msvc-${{ matrix.arch.name }}" >> $env:GITHUB_ENV "INSTALL_REF=$($env:GITHUB_REF -replace ".*/")" >> $env:GITHUB_ENV - "LUA_SUBPROJECT_PATH=subprojects/lua-5.4.4" >> $env:GITHUB_ENV + "LUA_SUBPROJECT_PATH=subprojects/$(awk -F ' *= *' '/directory/ { printf $2 }' subprojects/lua.wrap)" >> $env:GITHUB_ENV + - name: Download and patch subprojects + shell: bash + run: | + meson subprojects download + cat resources/windows/001-lua-unicode.diff | patch -Np1 -d "$LUA_SUBPROJECT_PATH" - name: Configure run: | - # Download the subprojects first so we can patch it before configuring. - # This avoids reconfiguring the subprojects when compiling. - meson subprojects download - Get-Content -Path resources/windows/001-lua-unicode.diff -Raw | patch -d $env:LUA_SUBPROJECT_PATH -p1 --forward meson setup --wrap-mode=forcefallback build - name: Build run: | diff --git a/scripts/build.sh b/scripts/build.sh index 778f596d..0908ab19 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -181,7 +181,7 @@ main() { # download the subprojects so we can start patching before configure. # this will prevent reconfiguring the project. meson subprojects download - lua_subproject_path=$(echo subprojects/lua-*/) + lua_subproject_path="subprojects/$(awk -F ' *= *' '/directory/ { printf $2 }' subprojects/lua.wrap)" if [[ -d $lua_subproject_path ]]; then patch -d $lua_subproject_path -p1 --forward < resources/windows/001-lua-unicode.diff fi From 513432a784156292ecbc2bdf8cf9f9510d114ab3 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:48:20 +0800 Subject: [PATCH 120/148] chore(deps): update freetype --- subprojects/freetype2.wrap | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/subprojects/freetype2.wrap b/subprojects/freetype2.wrap index 1ff89ecd..e3554c9a 100644 --- a/subprojects/freetype2.wrap +++ b/subprojects/freetype2.wrap @@ -1,9 +1,10 @@ [wrap-file] -directory = freetype-2.12.1 -source_url = https://download.savannah.gnu.org/releases/freetype/freetype-2.12.1.tar.xz -source_filename = freetype-2.12.1.tar.xz -source_hash = 4766f20157cc4cf0cd292f80bf917f92d1c439b243ac3018debf6b9140c41a7f -wrapdb_version = 2.12.1-2 +directory = freetype-2.13.2 +source_url = https://download.savannah.gnu.org/releases/freetype/freetype-2.13.2.tar.xz +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/freetype2_2.13.2-1/freetype-2.13.2.tar.xz +source_filename = freetype-2.13.2.tar.xz +source_hash = 12991c4e55c506dd7f9b765933e62fd2be2e06d421505d7950a132e4f1bb484d +wrapdb_version = 2.13.2-1 [provide] freetype2 = freetype_dep From 88dcb25396d207b052c6333b5c157c42a0f4b60e Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:49:34 +0800 Subject: [PATCH 121/148] chore(deps): update pcre2 --- subprojects/pcre2.wrap | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/subprojects/pcre2.wrap b/subprojects/pcre2.wrap index 8fada34e..6bfef6f3 100644 --- a/subprojects/pcre2.wrap +++ b/subprojects/pcre2.wrap @@ -1,12 +1,13 @@ [wrap-file] directory = pcre2-10.42 -source_url = https://github.com/PhilipHazel/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2 +source_url = https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2 source_filename = pcre2-10.42.tar.bz2 source_hash = 8d36cd8cb6ea2a4c2bb358ff6411b0c788633a2a45dabbf1aeb4b701d1b5e840 -patch_filename = pcre2_10.42-1_patch.zip -patch_url = https://wrapdb.mesonbuild.com/v2/pcre2_10.42-1/get_patch -patch_hash = 06969e916dfee663c189810df57d98574f15e0754a44cd93f3f0bc7234b05d89 -wrapdb_version = 10.42-1 +patch_filename = pcre2_10.42-5_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/pcre2_10.42-5/get_patch +patch_hash = 7ba1730a3786c46f41735658a9884b09bc592af3840716e0ccc552e7ddf5630c +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/pcre2_10.42-5/pcre2-10.42.tar.bz2 +wrapdb_version = 10.42-5 [provide] libpcre2-8 = libpcre2_8 From 9272f5ef2df87de39f11086cb79ac1c6a38191ea Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:53:25 +0800 Subject: [PATCH 122/148] chore(deps): update SDL2 --- meson.build | 15 ++++++++++++++- subprojects/sdl2.wrap | 19 +++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/meson.build b/meson.build index 5f7adcc4..19f85eb5 100644 --- a/meson.build +++ b/meson.build @@ -123,6 +123,7 @@ if not get_option('source-only') sdl_options += 'use_atomic=enabled' sdl_options += 'use_threads=enabled' sdl_options += 'use_timers=enabled' + sdl_options += 'with_main=true' # investigate if this is truly needed # Do not remove before https://github.com/libsdl-org/SDL/issues/5413 is released sdl_options += 'use_events=enabled' @@ -155,12 +156,24 @@ if not get_option('source-only') sdl_options += 'use_video_vulkan=disabled' sdl_options += 'use_video_offscreen=disabled' sdl_options += 'use_power=disabled' + sdl_options += 'system_iconv=disabled' sdl_dep = dependency('sdl2', fallback: ['sdl2', 'sdl2_dep'], default_options: default_fallback_options + sdl_options ) - lite_deps = [lua_dep, sdl_dep, freetype_dep, pcre2_dep, libm, libdl] + if host_machine.system() == 'windows' + if sdl_dep.type_name() == 'internal' + sdlmain_dep = dependency('sdl2main', fallback: ['sdl2main_dep']) + else + sdlmain_dep = cc.find_library('SDL2main') + endif + else + sdlmain_dep = dependency('', required: false) + assert(not sdlmain_dep.found(), 'checking if fake dependency has been found') + endif + + lite_deps = [lua_dep, sdl_dep, sdlmain_dep, freetype_dep, pcre2_dep, libm, libdl] endif #=============================================================================== # Install Configuration diff --git a/subprojects/sdl2.wrap b/subprojects/sdl2.wrap index 53a71e2f..14c18533 100644 --- a/subprojects/sdl2.wrap +++ b/subprojects/sdl2.wrap @@ -1,12 +1,15 @@ [wrap-file] -directory = SDL2-2.26.0 -source_url = https://github.com/libsdl-org/SDL/releases/download/release-2.26.0/SDL2-2.26.0.tar.gz -source_filename = SDL2-2.26.0.tar.gz -source_hash = 8000d7169febce93c84b6bdf376631f8179132fd69f7015d4dadb8b9c2bdb295 -patch_filename = sdl2_2.26.0-1_patch.zip -patch_url = https://wrapdb.mesonbuild.com/v2/sdl2_2.26.0-1/get_patch -patch_hash = 6fcfd727d71cf7837332723518d5e47ffd64f1e7630681cf4b50e99f2bf7676f -wrapdb_version = 2.26.0-1 +directory = SDL2-2.28.1 +source_url = https://github.com/libsdl-org/SDL/releases/download/release-2.28.1/SDL2-2.28.1.tar.gz +source_filename = SDL2-2.28.1.tar.gz +source_hash = 4977ceba5c0054dbe6c2f114641aced43ce3bf2b41ea64b6a372d6ba129cb15d +patch_filename = sdl2_2.28.1-2_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/sdl2_2.28.1-2/get_patch +patch_hash = 2dd332226ba2a4373c6d4eb29fa915e9d5414cf7bb9fa2e4a5ef3b16a06e2736 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sdl2_2.28.1-2/SDL2-2.28.1.tar.gz +wrapdb_version = 2.28.1-2 [provide] sdl2 = sdl2_dep +sdl2main = sdl2main_dep +sdl2_test = sdl2_test_dep From c31a8ae0f619a7010c32004a74066820c6bfae81 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 16:21:58 +0100 Subject: [PATCH 123/148] Scale mouse coordinates by window scale (#1630) * Update window scale on resize * Scale mouse coordinates by window scale * Avoid scaling mouse coordinates while using `LITE_USE_SDL_RENDERER` --- src/api/system.c | 20 ++++++++++---------- src/renderer.c | 1 + src/renwindow.c | 13 ++++++++++++- src/renwindow.h | 3 +++ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/api/system.c b/src/api/system.c index f7e0cf52..43f526f4 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -225,8 +225,8 @@ top: SDL_GetMouseState(&mx, &my); lua_pushstring(L, "filedropped"); lua_pushstring(L, e.drop.file); - lua_pushinteger(L, mx); - lua_pushinteger(L, my); + lua_pushinteger(L, mx * window_renderer.scale_x); + lua_pushinteger(L, my * window_renderer.scale_y); SDL_free(e.drop.file); return 4; @@ -283,8 +283,8 @@ top: if (e.button.button == 1) { SDL_CaptureMouse(1); } lua_pushstring(L, "mousepressed"); lua_pushstring(L, button_name(e.button.button)); - lua_pushinteger(L, e.button.x); - lua_pushinteger(L, e.button.y); + lua_pushinteger(L, e.button.x * window_renderer.scale_x); + lua_pushinteger(L, e.button.y * window_renderer.scale_y); lua_pushinteger(L, e.button.clicks); return 5; @@ -292,8 +292,8 @@ top: if (e.button.button == 1) { SDL_CaptureMouse(0); } lua_pushstring(L, "mousereleased"); lua_pushstring(L, button_name(e.button.button)); - lua_pushinteger(L, e.button.x); - lua_pushinteger(L, e.button.y); + lua_pushinteger(L, e.button.x * window_renderer.scale_x); + lua_pushinteger(L, e.button.y * window_renderer.scale_y); return 4; case SDL_MOUSEMOTION: @@ -305,10 +305,10 @@ top: e.motion.yrel += event_plus.motion.yrel; } lua_pushstring(L, "mousemoved"); - lua_pushinteger(L, e.motion.x); - lua_pushinteger(L, e.motion.y); - lua_pushinteger(L, e.motion.xrel); - lua_pushinteger(L, e.motion.yrel); + lua_pushinteger(L, e.motion.x * window_renderer.scale_x); + lua_pushinteger(L, e.motion.y * window_renderer.scale_y); + lua_pushinteger(L, e.motion.xrel * window_renderer.scale_x); + lua_pushinteger(L, e.motion.yrel * window_renderer.scale_y); return 5; case SDL_MOUSEWHEEL: diff --git a/src/renderer.c b/src/renderer.c index 0e36aaa1..70cc6a2d 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -520,6 +520,7 @@ void ren_init(SDL_Window *win) { void ren_resize_window(RenWindow *window_renderer) { renwin_resize_surface(window_renderer); + renwin_update_scale(window_renderer); } diff --git a/src/renwindow.c b/src/renwindow.c index fe40d009..15c9e86c 100644 --- a/src/renwindow.c +++ b/src/renwindow.c @@ -29,7 +29,8 @@ static void setup_renderer(RenWindow *ren, int w, int h) { #endif -void renwin_init_surface(UNUSED RenWindow *ren) { +void renwin_init_surface(RenWindow *ren) { + ren->scale_x = ren->scale_y = 1; #ifdef LITE_USE_SDL_RENDERER if (ren->rensurface.surface) { SDL_FreeSurface(ren->rensurface.surface); @@ -95,6 +96,16 @@ void renwin_resize_surface(UNUSED RenWindow *ren) { #endif } +void renwin_update_scale(RenWindow *ren) { +#ifndef LITE_USE_SDL_RENDERER + SDL_Surface *surface = SDL_GetWindowSurface(ren->window); + int window_w = surface->w, window_h = surface->h; + SDL_GetWindowSize(ren->window, &window_w, &window_h); + ren->scale_x = (float)surface->w / window_w; + ren->scale_y = (float)surface->h / window_h; +#endif +} + void renwin_show_window(RenWindow *ren) { SDL_ShowWindow(ren->window); } diff --git a/src/renwindow.h b/src/renwindow.h index a80586a0..364950de 100644 --- a/src/renwindow.h +++ b/src/renwindow.h @@ -6,6 +6,8 @@ struct RenWindow { uint8_t *command_buf; size_t command_buf_idx; size_t command_buf_size; + float scale_x; + float scale_y; #ifdef LITE_USE_SDL_RENDERER SDL_Renderer *renderer; SDL_Texture *texture; @@ -19,6 +21,7 @@ void renwin_init_command_buf(RenWindow *ren); void renwin_clip_to_surface(RenWindow *ren); void renwin_set_clip_rect(RenWindow *ren, RenRect rect); void renwin_resize_surface(RenWindow *ren); +void renwin_update_scale(RenWindow *ren); void renwin_show_window(RenWindow *ren); void renwin_update_rects(RenWindow *ren, RenRect *rects, int count); void renwin_free(RenWindow *ren); From 19cef97bcd0906ad29c3e28ac11ff3f785c994cc Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 16:33:34 +0100 Subject: [PATCH 124/148] Fix `core.redraw` when window is not focused (#1601) * Execute at least one step when window has no focus This way if `core.redraw` is set, it's respected. * Fully run threads at least once when window has no focus This allows threads that set `core.redraw` (like `projectsearch`) to continue running even after the window loses focus. "Fully" here means that `run_threads` has gone through *all* the "timed out" coroutines at least once. --- data/core/init.lua | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index 3f0cc096..6aead929 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -1378,29 +1378,40 @@ local run_threads = coroutine.wrap(function() -- stop running threads if we're about to hit the end of frame if system.get_time() - core.frame_start > max_time then - coroutine.yield(0) + coroutine.yield(0, false) end end - coroutine.yield(minimal_time_to_wake) + coroutine.yield(minimal_time_to_wake, true) end end) function core.run() local next_step + local last_frame_time + local run_threads_full = 0 while true do core.frame_start = system.get_time() - local time_to_wake = run_threads() + local time_to_wake, threads_done = run_threads() + if threads_done then + run_threads_full = run_threads_full + 1 + end local did_redraw = false - if not next_step or system.get_time() >= next_step then - did_redraw = core.step() + local did_step = false + local force_draw = core.redraw and last_frame_time and core.frame_start - last_frame_time > (1 / config.fps) + if force_draw or not next_step or system.get_time() >= next_step then + if core.step() then + did_redraw = true + last_frame_time = core.frame_start + end next_step = nil + did_step = true end if core.restart_request or core.quit_request then break end if not did_redraw then - if system.window_has_focus() then + if system.window_has_focus() or not did_step or run_threads_full < 2 then local now = system.get_time() if not next_step then -- compute the time until the next blink local t = now - core.blink_start @@ -1417,6 +1428,7 @@ function core.run() next_step = nil -- perform a step when we're not in focus if get we an event end else -- if we redrew, then make sure we only draw at most FPS/sec + run_threads_full = 0 local now = system.get_time() local elapsed = now - core.frame_start local next_frame = math.max(0, 1 / config.fps - elapsed) From 8eacca7ae146cc9c063a977b1e522fd7c1868928 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 16:40:47 +0100 Subject: [PATCH 125/148] Fix selecting newlines with `find-replace:select-add-{next,all}` (#1608) * Avoid adding existing selections in `select_add_next` * Use the first available selection as delimiter in `select_add_next` * Fix returning searches with newlines in `search.find` * Fix repeat search when the last result spanned multiple lines --- data/core/commands/findreplace.lua | 11 +++++++---- data/core/doc/search.lua | 13 ++++++++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/data/core/commands/findreplace.lua b/data/core/commands/findreplace.lua index 312e55b2..21b62c46 100644 --- a/data/core/commands/findreplace.lua +++ b/data/core/commands/findreplace.lua @@ -164,13 +164,16 @@ local function is_in_any_selection(line, col) end local function select_add_next(all) - local il1, ic1 = doc():get_selection(true) - for idx, l1, c1, l2, c2 in doc():get_selections(true, true) do + local il1, ic1 + for _, l1, c1, l2, c2 in doc():get_selections(true, true) do + if not il1 then + il1, ic1 = l1, c1 + end local text = doc():get_text(l1, c1, l2, c2) repeat l1, c1, l2, c2 = search.find(doc(), l2, c2, text, { wrap = true }) if l1 == il1 and c1 == ic1 then break end - if l2 and (all or not is_in_any_selection(l2, c2)) then + if l2 and not is_in_any_selection(l2, c2) then doc():add_selection(l2, c2, l1, c1) if not all then core.active_view:scroll_to_make_visible(l2, c2) @@ -253,7 +256,7 @@ command.add(valid_for_finding, { core.error("No find to continue from") else local sl1, sc1, sl2, sc2 = dv.doc:get_selection(true) - local line1, col1, line2, col2 = last_fn(dv.doc, sl1, sc2, last_text, case_sensitive, find_regex, false) + local line1, col1, line2, col2 = last_fn(dv.doc, sl2, sc2, last_text, case_sensitive, find_regex, false) if line1 then dv.doc:set_selection(line2, col2, line1, col1) dv:scroll_to_line(line2, true) diff --git a/data/core/doc/search.lua b/data/core/doc/search.lua index 8395769a..3cfe6a2d 100644 --- a/data/core/doc/search.lua +++ b/data/core/doc/search.lua @@ -66,7 +66,18 @@ function search.find(doc, line, col, text, opt) s, e = search_func(line_text, pattern, col, plain) end if s then - return line, s, line, e + 1 + local line2 = line + -- If we've matched the newline too, + -- return until the initial character of the next line. + if e >= #doc.lines[line] then + line2 = line + 1 + e = 0 + end + -- Avoid returning matches that go beyond the last line. + -- This is needed to avoid selecting the "last" newline. + if line2 <= #doc.lines then + return line, s, line2, e + 1 + end end col = opt.reverse and -1 or 1 end From b1a647814fc46baa62d4c35b41cfbe3e60300efb Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 16:45:53 +0100 Subject: [PATCH 126/148] Fix editing after undo not clearing the change id (#1574) --- data/core/doc/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index deeb3816..c3eeba87 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -488,6 +488,10 @@ end function Doc:insert(line, col, text) self.redo_stack = { idx = 1 } + -- Reset the clean id when we're pushing something new before it + if self:get_change_id() < self.clean_change_id then + self.clean_change_id = -1 + end line, col = self:sanitize_position(line, col) self:raw_insert(line, col, text, self.undo_stack, system.get_time()) self:on_text_change("insert") From 885e6b3c506c9a6c311ac96efef55f2ae079c450 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 17:00:09 +0100 Subject: [PATCH 127/148] Fix `language_js` regex constant detection (#1581) * Fix `language_js` regex constant detection * Simplify regex constant detection in `language_js` * Add more possessive quantifiers in `language_js` regex constant detection This avoids more catastrophic backtracking cases. * Allow `.` after regex constant in `language_js` --- data/plugins/language_js.lua | 74 ++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/data/plugins/language_js.lua b/data/plugins/language_js.lua index f79fece6..307aeecf 100644 --- a/data/plugins/language_js.lua +++ b/data/plugins/language_js.lua @@ -1,24 +1,74 @@ -- mod-version:3 local syntax = require "core.syntax" +-- Regex pattern explanation: +-- This will match / and will look ahead for something that looks like a regex. +-- +-- (?!/) Don't match empty regexes. +-- +-- (?>...) this is using an atomic group to minimize backtracking, as that'd +-- cause "Catastrophic Backtracking" in some cases. +-- +-- [^\\[\/]++ will match anything that's isn't an escape, a start of character +-- class or an end of pattern, without backtracking (the second +). +-- +-- \\. will match anything that's escaped. +-- +-- \[(?:[^\\\]++]|\\.)*+\] will match character classes. +-- +-- /[gmiyuvsd]*\s*[\n,;\)\]\}\.]) will match the end of pattern delimiter, optionally +-- followed by pattern options, and anything that can +-- be after a pattern. +-- +-- Demo with some unit tests (click on the Unit Tests entry): https://regex101.com/r/R0w8Qw/1 +-- Note that it has a couple of changes to make it work on that platform. +local regex_pattern = { + [=[/(?=(?!/)(?:(?>[^\\[\/]++|\\.|\[(?:[^\\\]]++|\\.)*+\])*+)++/[gmiyuvsd]*\s*[\n,;\)\]\}\.])()]=], + "/()[gmiyuvsd]*", "\\" +} + +-- For the moment let's not actually differentiate the insides of the regex, +-- as this will need new token types... +local inner_regex_syntax = { + patterns = { + { pattern = "%(()%?[:!=><]", type = { "string", "string" } }, + { pattern = "[.?+*%(%)|]", type = "string" }, + { pattern = "{%d*,?%d*}", type = "string" }, + { regex = { [=[\[()\^?]=], [=[(?:\]|(?=\n))()]=], "\\" }, + type = { "string", "string" }, + syntax = { -- Inside character class + patterns = { + { pattern = "\\\\", type = "string" }, + { pattern = "\\%]", type = "string" }, + { pattern = "[^%]\n]", type = "string" } + }, + symbols = {} + } + }, + { regex = "\\/", type = "string" }, + { regex = "[^/\n]", type = "string" }, + }, + symbols = {} +} + syntax.add { name = "JavaScript", files = { "%.js$", "%.json$", "%.cson$", "%.mjs$", "%.cjs$" }, comment = "//", block_comment = { "/*", "*/" }, patterns = { - { pattern = "//.*", type = "comment" }, - { pattern = { "/%*", "%*/" }, type = "comment" }, - { pattern = { '/[^= ]', '/', '\\' },type = "string" }, - { pattern = { '"', '"', '\\' }, type = "string" }, - { pattern = { "'", "'", '\\' }, type = "string" }, - { pattern = { "`", "`", '\\' }, type = "string" }, - { pattern = "0x[%da-fA-F_]+n?", type = "number" }, - { pattern = "-?%d+[%d%.eE_n]*", type = "number" }, - { pattern = "-?%.?%d+", type = "number" }, - { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, - { pattern = "[%a_][%w_]*%f[(]", type = "function" }, - { pattern = "[%a_][%w_]*", type = "symbol" }, + { pattern = "//.*", type = "comment" }, + { pattern = { "/%*", "%*/" }, type = "comment" }, + { regex = regex_pattern, syntax = inner_regex_syntax, type = {"string", "string"} }, + { pattern = { '"', '"', '\\' }, type = "string" }, + { pattern = { "'", "'", '\\' }, type = "string" }, + { pattern = { "`", "`", '\\' }, type = "string" }, + { pattern = "0x[%da-fA-F_]+n?()%s*()/?", type = {"number", "normal", "operator"} }, + { pattern = "-?%d+[%d%.eE_n]*()%s*()/?", type = {"number", "normal", "operator"} }, + { pattern = "-?%.?%d+()%s*()/?", type = {"number", "normal", "operator"} }, + { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, + { pattern = "[%a_][%w_]*%f[(]", type = "function" }, + { pattern = "[%a_][%w_]*()%s*()/?", type = {"symbol", "normal", "operator"} }, }, symbols = { ["async"] = "keyword", From 9be5a46a22fd1fea116aa4300fbfcdbcb14ebc40 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 17:11:46 +0100 Subject: [PATCH 128/148] Fix patterns starting with `^` in `tokenizer` (#1645) Previously the "dirty" version of the pattern was used, which could result in trying to match with multiple `^`, which failed valid matches. --- data/core/tokenizer.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/core/tokenizer.lua b/data/core/tokenizer.lua index 6d99d9c4..02ddcb75 100644 --- a/data/core/tokenizer.lua +++ b/data/core/tokenizer.lua @@ -210,9 +210,11 @@ function tokenizer.tokenize(incoming_syntax, text, state, resume) -- Remove '^' from the beginning of the pattern if type(target) == "table" then target[p_idx] = code:usub(2) + code = target[p_idx] else p.pattern = p.pattern and code:usub(2) p.regex = p.regex and code:usub(2) + code = p.pattern or p.regex end end end From bc935906d1ffdc26f996535461a06bd5fcc634aa Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 21:44:48 +0100 Subject: [PATCH 129/148] Use x offset to define render command rect in `rencache_draw_text` (#1618) * Return x offset for the first character in `ren_font_group_get_width` * Use x offset to define render command rect in `rencache_draw_text` --- src/api/renderer.c | 2 +- src/rencache.c | 5 +++-- src/renderer.c | 10 +++++++++- src/renderer.h | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/api/renderer.c b/src/api/renderer.c index 901824fe..6ef22023 100644 --- a/src/api/renderer.c +++ b/src/api/renderer.c @@ -198,7 +198,7 @@ static int f_font_get_width(lua_State *L) { size_t len; const char *text = luaL_checklstring(L, 2, &len); - lua_pushnumber(L, ren_font_group_get_width(&window_renderer, fonts, text, len)); + lua_pushnumber(L, ren_font_group_get_width(&window_renderer, fonts, text, len, NULL)); return 1; } diff --git a/src/rencache.c b/src/rencache.c index d28ed543..a77f82ca 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -191,8 +191,9 @@ void rencache_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color double rencache_draw_text(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, double x, int y, RenColor color) { - double width = ren_font_group_get_width(window_renderer, fonts, text, len); - RenRect rect = { x, y, (int)width, ren_font_group_get_height(fonts) }; + int x_offset; + double width = ren_font_group_get_width(window_renderer, fonts, text, len, &x_offset); + RenRect rect = { x + x_offset, y, (int)(width - x_offset), ren_font_group_get_height(fonts) }; if (rects_overlap(last_clip_rect, rect)) { int sz = len + 1; DrawTextCommand *cmd = push_command(window_renderer, DRAW_TEXT, sizeof(DrawTextCommand) + sz); diff --git a/src/renderer.c b/src/renderer.c index 70cc6a2d..cd5ec7ba 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -348,10 +348,11 @@ int ren_font_group_get_height(RenFont **fonts) { return fonts[0]->height; } -double ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len) { +double ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, const char *text, size_t len, int *x_offset) { double width = 0; const char* end = text + len; GlyphMetric* metric = NULL; GlyphSet* set = NULL; + bool set_x_offset = x_offset == NULL; while (text < end) { unsigned int codepoint; text = utf8_to_codepoint(text, &codepoint); @@ -359,8 +360,15 @@ double ren_font_group_get_width(RenWindow *window_renderer, RenFont **fonts, con if (!metric) break; width += (!font || metric->xadvance) ? metric->xadvance : fonts[0]->space_advance; + if (!set_x_offset) { + set_x_offset = true; + *x_offset = metric->bitmap_left; // TODO: should this be scaled by the surface scale? + } } const int surface_scale = renwin_get_surface(window_renderer).scale; + if (!set_x_offset) { + *x_offset = 0; + } return width / surface_scale; } diff --git a/src/renderer.h b/src/renderer.h index 0e96d9a9..1c865c8f 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -34,7 +34,7 @@ int ren_font_group_get_height(RenFont **font); float ren_font_group_get_size(RenFont **font); void ren_font_group_set_size(RenWindow *window_renderer, RenFont **font, float size); void ren_font_group_set_tab_size(RenFont **font, int n); -double ren_font_group_get_width(RenWindow *window_renderer, RenFont **font, const char *text, size_t len); +double ren_font_group_get_width(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, int *x_offset); double ren_draw_text(RenSurface *rs, RenFont **font, const char *text, size_t len, float x, int y, RenColor color); void ren_draw_rect(RenSurface *rs, RenRect rect, RenColor color); From 8e2928aeb88112f9a8301210943626b04f28485f Mon Sep 17 00:00:00 2001 From: Guldoman Date: Wed, 29 Nov 2023 22:12:22 +0100 Subject: [PATCH 130/148] Improve font/color change detection in `language_md` (#1614) * Delay setting font for custom `language_md` token types * Improve font/color change detection in `language_md` --- data/plugins/language_md.lua | 76 +++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 22 deletions(-) diff --git a/data/plugins/language_md.lua b/data/plugins/language_md.lua index 1046657d..8d8a855c 100644 --- a/data/plugins/language_md.lua +++ b/data/plugins/language_md.lua @@ -3,25 +3,6 @@ local syntax = require "core.syntax" local style = require "core.style" local core = require "core" -local initial_color = style.syntax["keyword2"] - --- Add 3 type of font styles for use on markdown files -for _, attr in pairs({"bold", "italic", "bold_italic"}) do - local attributes = {} - if attr ~= "bold_italic" then - attributes[attr] = true - else - attributes["bold"] = true - attributes["italic"] = true - end - style.syntax_fonts["markdown_"..attr] = style.code_font:copy( - style.code_font:get_size(), - attributes - ) - -- also add a color for it - style.syntax["markdown_"..attr] = style.syntax["keyword2"] -end - local in_squares_match = "^%[%]" local in_parenthesis_match = "^%(%)" @@ -224,12 +205,63 @@ syntax.add { -- Adjust the color on theme changes core.add_thread(function() + local custom_fonts = { bold = {font = nil, color = nil}, italic = {}, bold_italic = {} } + local initial_color + local last_code_font + + local function set_font(attr) + local attributes = {} + if attr ~= "bold_italic" then + attributes[attr] = true + else + attributes["bold"] = true + attributes["italic"] = true + end + local font = style.code_font:copy( + style.code_font:get_size(), + attributes + ) + custom_fonts[attr].font = font + style.syntax_fonts["markdown_"..attr] = font + end + + local function set_color(attr) + custom_fonts[attr].color = style.syntax["keyword2"] + style.syntax["markdown_"..attr] = style.syntax["keyword2"] + end + + -- Add 3 type of font styles for use on markdown files + for attr, _ in pairs(custom_fonts) do + -- Only set it if the font wasn't manually customized + if not style.syntax_fonts["markdown_"..attr] then + set_font(attr) + end + + -- Only set it if the color wasn't manually customized + if not style.syntax["markdown_"..attr] then + set_color(attr) + end + end + while true do - if initial_color ~= style.syntax["keyword2"] then - for _, attr in pairs({"bold", "italic", "bold_italic"}) do - style.syntax["markdown_"..attr] = style.syntax["keyword2"] + if last_code_font ~= style.code_font then + last_code_font = style.code_font + for attr, _ in pairs(custom_fonts) do + -- Only set it if the font wasn't manually customized + if style.syntax_fonts["markdown_"..attr] == custom_fonts[attr].font then + set_font(attr) + end end + end + + if initial_color ~= style.syntax["keyword2"] then initial_color = style.syntax["keyword2"] + for attr, _ in pairs(custom_fonts) do + -- Only set it if the color wasn't manually customized + if style.syntax["markdown_"..attr] == custom_fonts[attr].color then + set_color(attr) + end + end end coroutine.yield(1) end From 311651333af893e0f6ac4bc792a1ee8cf5de1181 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Thu, 30 Nov 2023 23:33:24 +0800 Subject: [PATCH 131/148] feat(process): allow commands and envs on proces_start (#1477) * feat(process): allow commands and envs on proces_start * refactor(process): copy process arguments once whenever possible Refactors the code to use an arglist type which is just lpCmdline on Windows and a list in Linux. The function automatically escapes the command when it is needed, avoiding a second copy. This also allows UTF-8 commands btw. * fix(process): fix invalid dereference * refactor(process): mark xstrdup as potentially unused * feat(process): add parent process environment when launching process * fix(process): fix operator precedence with array operators * fix(process): fix segfault when freeing random memory * fix(process): fix wrong check for setenv() * fix(process): fix accidentally initializing an array by assignment * fix(process): clear return value if success --- src/api/process.c | 422 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 328 insertions(+), 94 deletions(-) diff --git a/src/api/process.c b/src/api/process.c index d7bfeb72..66f27536 100644 --- a/src/api/process.c +++ b/src/api/process.c @@ -31,6 +31,8 @@ typedef DWORD process_error_t; typedef HANDLE process_stream_t; typedef HANDLE process_handle_t; +typedef wchar_t process_arglist_t[32767]; +typedef wchar_t *process_env_t; #define HANDLE_INVALID (INVALID_HANDLE_VALUE) #define PROCESS_GET_HANDLE(P) ((P)->process_information.hProcess) @@ -42,12 +44,20 @@ static volatile long PipeSerialNumber; typedef int process_error_t; typedef int process_stream_t; typedef pid_t process_handle_t; +typedef char **process_arglist_t; +typedef char **process_env_t; #define HANDLE_INVALID (0) #define PROCESS_GET_HANDLE(P) ((P)->pid) #endif +#ifdef __GNUC__ +#define UNUSED __attribute__((__unused__)) +#else +#define UNUSED +#endif + typedef struct { bool running, detached; int returncode, deadline; @@ -339,51 +349,264 @@ static bool signal_process(process_t* proc, signal_e sig) { return true; } -static int process_start(lua_State* L) { - int retval = 1; - size_t env_len = 0, key_len, val_len; - const char *cmd[256] = { NULL }, *env_names[256] = { NULL }, *env_values[256] = { NULL }, *cwd = NULL; - bool detach = false, literal = false; - int deadline = 10, new_fds[3] = { STDIN_FD, STDOUT_FD, STDERR_FD }; - size_t arg_len = lua_gettop(L), cmd_len; - if (lua_type(L, 1) == LUA_TTABLE) { - #if LUA_VERSION_NUM > 501 - lua_len(L, 1); - #else - lua_pushinteger(L, (int)lua_objlen(L, 1)); - #endif - cmd_len = luaL_checknumber(L, -1); lua_pop(L, 1); - if (!cmd_len) - // we have not allocated anything here yet, so we can skip cleanup code - // don't do this anywhere else! - return luaL_argerror(L, 1,"table cannot be empty"); - for (size_t i = 1; i <= cmd_len; ++i) { - lua_pushinteger(L, i); - lua_rawget(L, 1); - cmd[i-1] = luaL_checkstring(L, -1); - } + +static UNUSED char *xstrdup(const char *str) { + char *result = str ? malloc(strlen(str) + 1) : NULL; + if (result) strcpy(result, str); + return result; +} + + +static int process_arglist_init(process_arglist_t *list, size_t *list_len, size_t nargs) { + *list_len = 0; +#ifdef _WIN32 + memset(*list, 0, sizeof(process_arglist_t)); +#else + *list = calloc(sizeof(char *), nargs + 1); + if (!*list) return ENOMEM; +#endif + return 0; +} + + +static int process_arglist_add(process_arglist_t *list, size_t *list_len, const char *arg, bool escape) { + size_t len = *list_len; +#ifdef _WIN32 + int arg_len; + wchar_t *cmdline = *list; + wchar_t arg_w[32767]; + // this length includes the null terminator! + if (!(arg_len = MultiByteToWideChar(CP_UTF8, 0, arg, -1, arg_w, 32767))) + return GetLastError(); + if (arg_len + len > 32767) + return ERROR_NOT_ENOUGH_MEMORY; + + if (!escape) { + // replace the current null terminator with a space + if (len > 0) cmdline[len-1] = ' '; + memcpy(cmdline + len, arg_w, arg_len * sizeof(wchar_t)); + len += arg_len; } else { - literal = true; - cmd[0] = luaL_checkstring(L, 1); - cmd_len = 1; + // if the string contains spaces, then we must quote it + bool quote = wcspbrk(arg_w, L" \t\v\r\n"); + int backslash = 0, escaped_len = quote ? 2 : 0; + for (int i = 0; i < arg_len; i++) { + if (arg_w[i] == L'\\') { + backslash++; + } else if (arg_w[i] == L'"') { + escaped_len += backslash + 1; + backslash = 0; + } else { + backslash = 0; + } + escaped_len++; + } + // escape_len contains NUL terminator + if (escaped_len + len > 32767) + return ERROR_NOT_ENOUGH_MEMORY; + // replace our previous NUL terminator with space + if (len > 0) cmdline[len-1] = L' '; + if (quote) cmdline[len++] = L'"'; + // we are not going to iterate over NUL terminator + for (int i = 0;arg_w[i]; i++) { + if (arg_w[i] == L'\\') { + backslash++; + } else if (arg_w[i] == L'"') { + // add backslash + 1 backslashes + for (int j = 0; j < backslash; j++) + cmdline[len++] = L'\\'; + cmdline[len++] = L'\\'; + backslash = 0; + } else { + backslash = 0; + } + cmdline[len++] = arg_w[i]; + } + if (quote) cmdline[len++] = L'"'; + cmdline[len++] = L'\0'; + } +#else + char **cmd = *list; + cmd[len] = xstrdup(arg); + if (!cmd[len]) return ENOMEM; + len++; +#endif + *list_len = len; + return 0; +} + + +static void process_arglist_free(process_arglist_t *list) { +#ifndef _WIN32 + char **cmd = *list; + for (int i = 0; cmd[i]; i++) + free(cmd[i]); + free(cmd); + *list = NULL; +#endif +} + + +static int process_env_init(process_env_t *env_list, size_t *env_len, size_t nenv) { + *env_len = 0; +#ifdef _WIN32 + *env_list = NULL; +#else + *env_list = calloc(sizeof(char *), nenv * 2); + if (!*env_list) return ENOMEM; +#endif + return 0; +} + + +#ifdef _WIN32 +static int cmp_name(wchar_t *a, wchar_t *b) { + wchar_t _A[32767], _B[32767], *A = _A, *B = _B, *a_eq, *b_eq; + int na, nb, r; + a_eq = wcschr(a, L'='); + b_eq = wcschr(b, L'='); + assert(a_eq); + assert(b_eq); + na = a_eq - a; + nb = b_eq - b; + r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, a, na, A, na); + assert(r == na); + A[na] = L'\0'; + r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, b, nb, B, nb); + assert(r == nb); + B[nb] = L'\0'; + + for (;;) { + wchar_t AA = *A++, BB = *B++; + if (AA > BB) + return 1; + else if (AA < BB) + return -1; + else if (!AA && !BB) + return 0; + } +} + + +static int process_env_add_variable(process_env_t *env_list, size_t *env_list_len, wchar_t *var, size_t var_len) { + wchar_t *list, *list_p; + size_t block_var_len, list_len; + list = list_p = *env_list; + list_len = *env_list_len; + if (list_len) { + // check if it is already in the block + while ((block_var_len = wcslen(list_p))) { + if (cmp_name(list_p, var) == 0) + return -1; // already installed + list_p += block_var_len + 1; + } + } + // allocate list + 1 characters for the block terminator + list = realloc(list, (list_len + var_len + 1) * sizeof(wchar_t)); + if (!list) return ERROR_NOT_ENOUGH_MEMORY; + // copy the env variable to the block + memcpy(list + list_len, var, var_len * sizeof(wchar_t)); + // terminate the block again + list[list_len + var_len] = L'\0'; + *env_list = list; + *env_list_len = (list_len + var_len); + return 0; +} + + +static int process_env_add_system(process_env_t *env_list, size_t *env_list_len) { + int retval = 0; + wchar_t *proc_env_block, *proc_env_block_p; + int proc_env_len; + + proc_env_block = proc_env_block_p = GetEnvironmentStringsW(); + while ((proc_env_len = wcslen(proc_env_block_p))) { + // try to add it to the list + if ((retval = process_env_add_variable(env_list, env_list_len, proc_env_block_p, proc_env_len + 1)) > 0) + goto cleanup; + proc_env_block_p += proc_env_len + 1; + } + retval = 0; + +cleanup: + if (proc_env_block) FreeEnvironmentStringsW(proc_env_block); + return retval; +} +#endif + + +static int process_env_add(process_env_t *env_list, size_t *env_len, const char *key, const char *value) { +#ifdef _WIN32 + wchar_t env_var[32767]; + int r, var_len = 0; + if (!(r = MultiByteToWideChar(CP_UTF8, 0, key, -1, env_var, 32767))) + return GetLastError(); + var_len += r; + env_var[var_len-1] = L'='; + if (!(r = MultiByteToWideChar(CP_UTF8, 0, value, -1, env_var + var_len, 32767 - var_len))) + return GetLastError(); + var_len += r; + return process_env_add_variable(env_list, env_len, env_var, var_len); +#else + (*env_list)[*env_len] = xstrdup(key); + if (!(*env_list)[*env_len]) + return ENOMEM; + (*env_list)[*env_len + 1] = xstrdup(value); + if (!(*env_list)[*env_len + 1]) + return ENOMEM; + *env_len += 2; +#endif + return 0; +} + + +static void process_env_free(process_env_t *list) { + if (!*list) return; +#ifdef _WIN32 + free(*list); +#else + for (size_t i = 0; (*list)[i]; i++) free((*list)[i]); + free(*list); +#endif + *list = NULL; +} + + +static int process_start(lua_State* L) { + int r, retval = 1; + size_t env_len = 0, cmd_len = 0, arglist_len = 0, env_vars_len = 0; + process_arglist_t arglist; + process_env_t env_vars = NULL; + const char *cwd = NULL; + bool detach = false, escape = true; + int deadline = 10, new_fds[3] = { STDIN_FD, STDOUT_FD, STDERR_FD }; + + if (lua_isstring(L, 1)) { + escape = false; + // create a table that contains the string as the value + lua_createtable(L, 1, 0); + lua_pushvalue(L, 1); + lua_rawseti(L, -2, 1); + lua_replace(L, 1); } - if (arg_len > 1) { - lua_getfield(L, 2, "env"); - if (!lua_isnil(L, -1)) { - lua_pushnil(L); - while (lua_next(L, -2) != 0) { - const char* key = luaL_checklstring(L, -2, &key_len); - const char* val = luaL_checklstring(L, -1, &val_len); - env_names[env_len] = malloc(key_len+1); - strcpy((char*)env_names[env_len], key); - env_values[env_len] = malloc(val_len+1); - strcpy((char*)env_values[env_len], val); - lua_pop(L, 1); - ++env_len; - } - } else - lua_pop(L, 1); + luaL_checktype(L, 1, LUA_TTABLE); + #if LUA_VERSION_NUM > 501 + lua_len(L, 1); + #else + lua_pushinteger(L, (int)lua_objlen(L, 1)); + #endif + cmd_len = luaL_checknumber(L, -1); lua_pop(L, 1); + if (!cmd_len) + return luaL_argerror(L, 1, "table cannot be empty"); + // check if each arguments is a string + for (size_t i = 1; i <= cmd_len; ++i) { + lua_rawgeti(L, 1, i); + luaL_checkstring(L, -1); + lua_pop(L, 1); + } + + if (lua_istable(L, 2)) { lua_getfield(L, 2, "detach"); detach = lua_toboolean(L, -1); lua_getfield(L, 2, "timeout"); deadline = luaL_optnumber(L, -1, deadline); lua_getfield(L, 2, "cwd"); cwd = luaL_optstring(L, -1, NULL); @@ -391,20 +614,70 @@ static int process_start(lua_State* L) { lua_getfield(L, 2, "stdout"); new_fds[STDOUT_FD] = luaL_optnumber(L, -1, STDOUT_FD); lua_getfield(L, 2, "stderr"); new_fds[STDERR_FD] = luaL_optnumber(L, -1, STDERR_FD); for (int stream = STDIN_FD; stream <= STDERR_FD; ++stream) { - if (new_fds[stream] > STDERR_FD || new_fds[stream] < REDIRECT_PARENT) { - lua_pushfstring(L, "error: redirect to handles, FILE* and paths are not supported"); + if (new_fds[stream] > STDERR_FD || new_fds[stream] < REDIRECT_PARENT) + return luaL_error(L, "error: redirect to handles, FILE* and paths are not supported"); + } + lua_pop(L, 6); // pop all the values above + + luaL_getsubtable(L, 2, "env"); + // count environment variobles + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + luaL_checkstring(L, -2); + luaL_checkstring(L, -1); + lua_pop(L, 1); + env_len++; + } + + if (env_len) { + if ((r = process_env_init(&env_vars, &env_vars_len, env_len)) != 0) { retval = -1; + push_error(L, "cannot allocate environment list", r); goto cleanup; } + + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + if ((r = process_env_add(&env_vars, &env_vars_len, lua_tostring(L, -2), lua_tostring(L, -1))) != 0) { + retval = -1; + push_error(L, "cannot copy environment variable", r); + goto cleanup; + } + lua_pop(L, 1); + env_len++; + } } } + // allocate and copy commands + if ((r = process_arglist_init(&arglist, &arglist_len, cmd_len)) != 0) { + retval = -1; + push_error(L, "cannot create argument list", r); + goto cleanup; + } + for (size_t i = 1; i <= cmd_len; i++) { + lua_rawgeti(L, 1, i); + if ((r = process_arglist_add(&arglist, &arglist_len, lua_tostring(L, -1), escape)) != 0) { + retval = -1; + push_error(L, "cannot add argument", r); + goto cleanup; + } + lua_pop(L, 1); + } + process_t* self = lua_newuserdata(L, sizeof(process_t)); memset(self, 0, sizeof(process_t)); luaL_setmetatable(L, API_TYPE_PROCESS); self->deadline = deadline; self->detached = detach; #if _WIN32 + if (env_vars) { + if ((r = process_env_add_system(&env_vars, &env_vars_len)) != 0) { + retval = -1; + push_error(L, "cannot add environment variable", r); + goto cleanup; + } + } for (int i = 0; i < 3; ++i) { switch (new_fds[i]) { case REDIRECT_PARENT: @@ -455,7 +728,7 @@ static int process_start(lua_State* L) { self->child_pipes[i][1] = self->child_pipes[new_fds[i]][1]; } } - STARTUPINFO siStartInfo; + STARTUPINFOW siStartInfo; memset(&self->process_information, 0, sizeof(self->process_information)); memset(&siStartInfo, 0, sizeof(siStartInfo)); siStartInfo.cb = sizeof(siStartInfo); @@ -463,48 +736,10 @@ static int process_start(lua_State* L) { siStartInfo.hStdInput = self->child_pipes[STDIN_FD][0]; siStartInfo.hStdOutput = self->child_pipes[STDOUT_FD][1]; siStartInfo.hStdError = self->child_pipes[STDERR_FD][1]; - char commandLine[32767] = { 0 }, environmentBlock[32767], wideEnvironmentBlock[32767*2]; - int offset = 0; - if (!literal) { - for (size_t i = 0; i < cmd_len; ++i) { - size_t len = strlen(cmd[i]); - if (offset + len + 2 >= sizeof(commandLine)) break; - if (i > 0) - commandLine[offset++] = ' '; - commandLine[offset++] = '"'; - int backslashCount = 0; // Yes, this is necessary. - for (size_t j = 0; j < len && offset + 2 + backslashCount < sizeof(commandLine); ++j) { - if (cmd[i][j] == '\\') - ++backslashCount; - else if (cmd[i][j] == '"') { - for (size_t k = 0; k < backslashCount; ++k) - commandLine[offset++] = '\\'; - commandLine[offset++] = '\\'; - backslashCount = 0; - } else - backslashCount = 0; - commandLine[offset++] = cmd[i][j]; - } - if (offset + 1 + backslashCount >= sizeof(commandLine)) break; - for (size_t k = 0; k < backslashCount; ++k) - commandLine[offset++] = '\\'; - commandLine[offset++] = '"'; - } - commandLine[offset] = 0; - } else { - strncpy(commandLine, cmd[0], sizeof(commandLine)); - } - offset = 0; - for (size_t i = 0; i < env_len; ++i) { - if (offset + strlen(env_values[i]) + strlen(env_names[i]) + 1 >= sizeof(environmentBlock)) - break; - offset += snprintf(&environmentBlock[offset], sizeof(environmentBlock) - offset, "%s=%s", env_names[i], env_values[i]); - environmentBlock[offset++] = 0; - } - environmentBlock[offset++] = 0; - if (env_len > 0) - MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, environmentBlock, offset, (LPWSTR)wideEnvironmentBlock, sizeof(wideEnvironmentBlock)); - if (!CreateProcess(NULL, commandLine, NULL, NULL, true, (detach ? DETACHED_PROCESS : CREATE_NO_WINDOW) | CREATE_UNICODE_ENVIRONMENT, env_len > 0 ? wideEnvironmentBlock : NULL, cwd, &siStartInfo, &self->process_information)) { + wchar_t cwd_w[MAX_PATH]; + if (cwd) // TODO: error handling + MultiByteToWideChar(CP_UTF8, 0, cwd, -1, cwd_w, MAX_PATH); + if (!CreateProcessW(NULL, arglist, NULL, NULL, true, (detach ? DETACHED_PROCESS : CREATE_NO_WINDOW) | CREATE_UNICODE_ENVIRONMENT, env_vars, cwd ? cwd_w : NULL, &siStartInfo, &self->process_information)) { push_error(L, NULL, GetLastError()); retval = -1; goto cleanup; @@ -552,9 +787,9 @@ static int process_start(lua_State* L) { close(self->child_pipes[stream][stream == STDIN_FD ? 1 : 0]); } size_t set; - for (set = 0; set < env_len && setenv(env_names[set], env_values[set], 1) == 0; ++set); - if (set == env_len && (!detach || setsid() != -1) && (!cwd || chdir(cwd) != -1)) - execvp(cmd[0], (char** const)cmd); + for (set = 0; set < env_vars_len && setenv(env_vars[set], env_vars[set+1], 1) == 0; set += 2); + if (set == env_vars_len && (!detach || setsid() != -1) && (!cwd || chdir(cwd) != -1)) + execvp(arglist[0], (char** const)arglist); write(control_pipe[1], &errno, sizeof(errno)); _exit(-1); } @@ -588,16 +823,15 @@ static int process_start(lua_State* L) { if (control_pipe[0]) close(control_pipe[0]); if (control_pipe[1]) close(control_pipe[1]); #endif - for (size_t i = 0; i < env_len; ++i) { - free((char*)env_names[i]); - free((char*)env_values[i]); - } for (int stream = 0; stream < 3; ++stream) { process_stream_t* pipe = &self->child_pipes[stream][stream == STDIN_FD ? 0 : 1]; if (*pipe) { close_fd(pipe); } } + process_arglist_free(&arglist); + process_env_free(&env_vars); + if (retval == -1) return lua_error(L); From 34cebe8fe407e54d2114c97148d00e0bbe31f61a Mon Sep 17 00:00:00 2001 From: Guldoman Date: Fri, 27 Oct 2023 13:39:08 +0200 Subject: [PATCH 132/148] Make license time-independent (#1655) --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index da7be0e2..387fd09d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2021 Lite XL Team +Copyright (c) 2020-present Lite XL Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From f1bdd840a1b1c13cc5162979d886ed241a9ba26a Mon Sep 17 00:00:00 2001 From: ThaCuber <70547062+thacuber2a03@users.noreply.github.com> Date: Sat, 2 Dec 2023 18:44:07 -0400 Subject: [PATCH 133/148] fix nagbar failed save message (#1678) * fix nagbar failed save message - visually separated statements with a `.` - first statement slightly rewritten - use `'` rather than `"` * yeahhhh no back to `"` --- data/core/commands/doc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index e840dbab..1155ac26 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -43,7 +43,7 @@ local function save(filename) core.log("Saved \"%s\"", saved_filename) else core.error(err) - core.nag_view:show("Saving failed", string.format("Could not save \"%s\" do you want to save to another location?", doc().filename), { + core.nag_view:show("Saving failed", string.format("Couldn't save file \"%s\". Do you want to save to another location?", doc().filename), { { text = "No", default_no = true }, { text = "Yes", default_yes = true } }, function(item) From 1d4e01a19267c48655ae3b3d626bb7ddd6105d7a Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Sun, 3 Dec 2023 11:09:56 -0500 Subject: [PATCH 134/148] Fixed a minor bug, should close issue #1680. --- data/plugins/drawwhitespace.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/plugins/drawwhitespace.lua b/data/plugins/drawwhitespace.lua index ef69107f..5c174356 100644 --- a/data/plugins/drawwhitespace.lua +++ b/data/plugins/drawwhitespace.lua @@ -308,7 +308,7 @@ end command.add(nil, { ["draw-whitespace:toggle"] = function() - config.plugins.drawwhitespace.enabled = not config.drawwhitespace.enabled + config.plugins.drawwhitespace.enabled = not config.plugins.drawwhitespace.enabled end, ["draw-whitespace:disable"] = function() From 9c21903af70242af2f886d3368048a626ab15ee3 Mon Sep 17 00:00:00 2001 From: vqn <85911372+vqns@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:54:52 +0000 Subject: [PATCH 135/148] add autocompletion to multicursor (#1394) * use Doc:remove --- data/plugins/autocomplete.lua | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/data/plugins/autocomplete.lua b/data/plugins/autocomplete.lua index 5921e838..cf228b6e 100644 --- a/data/plugins/autocomplete.lua +++ b/data/plugins/autocomplete.lua @@ -631,7 +631,6 @@ end command.add(predicate, { ["autocomplete:complete"] = function(dv) local doc = dv.doc - local line, col = doc:get_selection() local item = suggestions[suggestions_idx] local text = item.text local inserted = false @@ -640,9 +639,23 @@ command.add(predicate, { end if not inserted then local current_partial = get_partial_symbol() - doc:insert(line, col, text) - doc:remove(line, col, line, col - #current_partial) - doc:set_selection(line, col + #text - #current_partial) + local sz = #current_partial + + for idx, line1, col1, line2, col2 in doc:get_selections(true) do + local n = col1 - 1 + local line = doc.lines[line1] + for i = 1, sz + 1 do + local j = sz - i + local subline = line:sub(n - j, n) + local subpartial = current_partial:sub(i, -1) + if subpartial == subline then + doc:remove(line1, col1, line2, n - j) + break + end + end + end + + doc:text_input(item.text) end reset_suggestions() end, From 97a49661e08b45d8aa0934facc5f94a8874a1081 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Fri, 8 Dec 2023 22:00:10 +0800 Subject: [PATCH 136/148] chore: update versions --- .github/workflows/release.yml | 2 +- meson.build | 2 +- resources/linux/org.lite_xl.lite_xl.appdata.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5d9a388c..e788ab1f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ on: inputs: version: description: Release Version - default: v2.1.1 + default: v2.1.2 required: true jobs: diff --git a/meson.build b/meson.build index 19f85eb5..72dc0588 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('lite-xl', ['c'], - version : '2.1.1', + version : '2.1.2', license : 'MIT', meson_version : '>= 0.56', default_options : [ diff --git a/resources/linux/org.lite_xl.lite_xl.appdata.xml b/resources/linux/org.lite_xl.lite_xl.appdata.xml index b707ebe1..761e4e68 100644 --- a/resources/linux/org.lite_xl.lite_xl.appdata.xml +++ b/resources/linux/org.lite_xl.lite_xl.appdata.xml @@ -29,6 +29,6 @@ - + From b68efcd9e44547eeafa46a152c0656c4f42035cd Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:51:49 +0800 Subject: [PATCH 137/148] chore(changelog): update changelog for v2.1.2 --- changelog.md | 419 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 419 insertions(+) diff --git a/changelog.md b/changelog.md index b1d6c9d8..7fecb1cb 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,423 @@ # Changes Log +## [2.1.2] - 2023-12-29 + +This release addresses some issues present in the previous release, +and improves the performance and stability of Lite XL. + +### New Features + +* The context menu in TreeView is now navigable with a keyboard. + ([#1338](https://github.com/lite-xl/lite-xl/pull/1338)) + +* A universal build of Lite XL is now available for macOS. + This build runs natively on both Intel and Apple Silicon macs. + ([#1458](https://github.com/lite-xl/lite-xl/pull/1458)) + +* Most Unicode characters should be displayed properly + if your fonts support them. + ([#1524](https://github.com/lite-xl/lite-xl/pull/1524)) + +* LogView will no longer scroll automatically if the user had scrolled. + The LogView will only scroll automatically when the user scrolls up + to the last entry. + ([#1546](https://github.com/lite-xl/lite-xl/pull/1546)) + +* When using different fonts (especially fonts that render different scripts), + the letters will be aligned vertically. + ([#1560](https://github.com/lite-xl/lite-xl/pull/1560)) + +* Unsaved named files are now saved in the workspace. + ([#1597](https://github.com/lite-xl/lite-xl/pull/1597)) + +* macOS builds are now signed with a developer certificate. + This allows the user to right click the application in Finder and execute + it directly. + ([#1656](https://github.com/lite-xl/lite-xl/pull/1656)) + +### Performance Improvements + +* Allow command buffer to be expanded. + ([#1297](https://github.com/lite-xl/lite-xl/pull/1297)) + +* Use table.move to implement `common.splice`. + ([#1324](https://github.com/lite-xl/lite-xl/pull/1324)) + +* Create renderer only when it doesn't exist. + ([#1315](https://github.com/lite-xl/lite-xl/pull/1315)) + +* Avoid drawing hidden text in `DocView:draw_line_text`. + ([#1298](https://github.com/lite-xl/lite-xl/pull/1298)) + +* Don't calculate widths per-uft8-char when not needed. + ([#1409](https://github.com/lite-xl/lite-xl/pull/1409)) + +* Allow tokenizer to pause and resume in the middle of a line. + ([#1444](https://github.com/lite-xl/lite-xl/pull/1444)) + +* Optimize CI build times on MSYS2. + ([#1435](https://github.com/lite-xl/lite-xl/pull/1435)) + +* Significant memory usage improvements when using huge fonts on Windows. + ([#1555](https://github.com/lite-xl/lite-xl/pull/1555)) + +* Optimize background tasks response time. + ([#1601](https://github.com/lite-xl/lite-xl/pull/1601)) + +### Backward Incompatible Changes + +* The native plugin API is now usable on multiple source files, + without causing any duplicated symbol errors during compilation. + Plugins using the new plugin API header must define `LITE_XL_PLUGIN_ENTRYPOINT` + before importing the header, in one of their source files. + ([#1335](https://github.com/lite-xl/lite-xl/pull/1335)) + +* The native plugin API header now follows the Lua 5.4 API. + Previously, the plugin API header followed the Lua 5.2 API. + ([#1436](https://github.com/lite-xl/lite-xl/pull/1436)) + +* On Linux, `process.start()` will now throw an error if `execv()` fails. + ([#1363](https://github.com/lite-xl/lite-xl/pull/1363)) + +* Lite XL will use the default `SCALE` of 1 due to unreliable display + scale detection. This may be fixed in a later version of Lite XL. + Set the `LITE_SCALE` environment variable to override this value. + +### Fixes + +* Fix minor typos in user module + ([#1289](https://github.com/lite-xl/lite-xl/pull/1289)) + +* Do not allow users to create an empty font group + ([#1303](https://github.com/lite-xl/lite-xl/pull/1303)) + +* Fix a memory leak + ([#1305](https://github.com/lite-xl/lite-xl/pull/1305)) + +* Make dirwatch sorting compatible with what file_bisect expects + ([#1300](https://github.com/lite-xl/lite-xl/pull/1300)) + +* Handle readlink errors + ([#1292](https://github.com/lite-xl/lite-xl/pull/1292)) + +* Disable horizontal scrolling when linewrapping is enabled + ([#1309](https://github.com/lite-xl/lite-xl/pull/1309)) + +* Update widgets install location + +* Add missing luaL_typeerror symbol to plugin API + ([#1313](https://github.com/lite-xl/lite-xl/pull/1313)) + +* Defer lua error until after cleanup + ([#1310](https://github.com/lite-xl/lite-xl/pull/1310)) + +* Make empty groups in regex.gmatch return their offset + ([#1325](https://github.com/lite-xl/lite-xl/pull/1325)) + +* Add missing header declaration + +* Fix msys build now requiring ca-certificates + ([#1348](https://github.com/lite-xl/lite-xl/pull/1348)) + +* Fix path to macOS arm64 cross file in GitHub workflows + +* Fix Doc contextmenu not registering commands if scale plugin is not found + ([#1338](https://github.com/lite-xl/lite-xl/pull/1338)) + +* Fix TreeView contextmenu commands not working if the mouse hovers DocView + ([#1338](https://github.com/lite-xl/lite-xl/pull/1338)) + +* Fix incorrect contextmenu predicate + ([#1338](https://github.com/lite-xl/lite-xl/pull/1338)) + +* Properly rescale NagView on scale change + ([#1379](https://github.com/lite-xl/lite-xl/pull/1379)) + +* Scale plugin also rescales `style.expanded_scrollbar_size` + ([#1380](https://github.com/lite-xl/lite-xl/pull/1380)) + +* Improve DocView:get_visible_line_range precision + ([#1382](https://github.com/lite-xl/lite-xl/pull/1382)) + +* Fix up some post 5.1/JIT Symbols + ([#1385](https://github.com/lite-xl/lite-xl/pull/1385)) + +* Fix incorrect x_offset if opened docs have different tab sizes + ([#1383](https://github.com/lite-xl/lite-xl/pull/1383)) + +* Use correct view for scrolling to find-replace:repeat-find results + ([#1400](https://github.com/lite-xl/lite-xl/pull/1400)) + +* Improve text width calculation precision + ([#1408](https://github.com/lite-xl/lite-xl/pull/1408)) + +* Add asynchronous process reaping + ([#1412](https://github.com/lite-xl/lite-xl/pull/1412)) + +* Fix cursors positions when deleting multiple selections + ([#1393](https://github.com/lite-xl/lite-xl/pull/1393), + [#1463](https://github.com/lite-xl/lite-xl/pull/1463)) + +* Fix invalid EXEFILE and EXEDIR on Windows + ([#1396](https://github.com/lite-xl/lite-xl/pull/1396)) + +* Fix `os.getenv()` not supporting UTF-8 output + ([#1397](https://github.com/lite-xl/lite-xl/pull/1397)) + +* Fix differing stacktrace on stdout and file + ([#1404](https://github.com/lite-xl/lite-xl/pull/1404)) + +* Update api_require to expose more symbols + ([#1437](https://github.com/lite-xl/lite-xl/pull/1437)) + +* Make system.path_compare more case-aware + ([#1457](https://github.com/lite-xl/lite-xl/pull/1457)) + +* Fix for api_require wrong macro && conditions + ([#1465](https://github.com/lite-xl/lite-xl/pull/1465)) + +* Merge carets after doc:move-to-{previous,next}-char + ([#1462](https://github.com/lite-xl/lite-xl/pull/1462)) + +* Process API improvements (again) + ([#1370](https://github.com/lite-xl/lite-xl/pull/1370)) + +* Make system.path_compare more digit-aware + ([#1474](https://github.com/lite-xl/lite-xl/pull/1474)) + +* Check for HANDLE_INVALID in Process API + ([#1475](https://github.com/lite-xl/lite-xl/pull/1475)) + +* Fix linewrapping bug to do with wordwrapping + +* Fix compiler warning for printing size_t in rencache.c + +* Return error string from C searcher + +* Restore horizontal scroll position after scale change + ([#494](https://github.com/lite-xl/lite-xl/pull/494)) + +* Fix memory leak in renderer.c when freeing glyphsets + +* Move lineguide below blinking cursor + ([#1511](https://github.com/lite-xl/lite-xl/pull/1511)) + +* Close lua state when exiting on a runtime error + ([#1487](https://github.com/lite-xl/lite-xl/pull/1487)) + +* Mark linewrapping open_files table as weak + +* Don't use core.status_view if not yet initialized when logging + +* Revert "core syntax: strip the path from filename on syntax.get ([#1168](https://github.com/lite-xl/lite-xl/pull/1168))" + ([#1322](https://github.com/lite-xl/lite-xl/pull/1322)) + +* Make Doc:sanitize_position return a more appropriate col + ([#1469](https://github.com/lite-xl/lite-xl/pull/1469)) + +* Skip checking files if no filename was provided to syntax.get + +* Normalize stroke before adding keybind + ([#1334](https://github.com/lite-xl/lite-xl/pull/1334)) + +* Make DocView aware of scrollbars sizes + ([#1177](https://github.com/lite-xl/lite-xl/pull/1177)) + +* Normalize strokes in fixed order + ([#1572](https://github.com/lite-xl/lite-xl/pull/1572)) + +* Defer core:open-log until everything is loaded + ([#1585](https://github.com/lite-xl/lite-xl/pull/1585)) + +* Fix returned percent when clicking the Scrollbar track + +* Fix C++14 digit separators + ([#1593](https://github.com/lite-xl/lite-xl/pull/1593)) + +* Make linewrapping consider the expanded Scrollbar size + +* Fix dimmed text when antialiasing is turned off + ([#1641](https://github.com/lite-xl/lite-xl/pull/1641)) + +* Mark unsaved named files as dirty + ([#1598](https://github.com/lite-xl/lite-xl/pull/1598)) + +* Make `common.serialize()` locale-independent and nan/inf compatible + ([#1640](https://github.com/lite-xl/lite-xl/pull/1640)) + +* Ignore keypresses during IME composition + ([#1573](https://github.com/lite-xl/lite-xl/pull/1573)) + +* Fix deadlock if error handler jumps somewhere else + ([#1647](https://github.com/lite-xl/lite-xl/pull/1647)) + +* Avoid considering single spaces in detectindent + ([#1595](https://github.com/lite-xl/lite-xl/pull/1595)) + +* Fix deleting indentation with multiple cursors + ([#1670](https://github.com/lite-xl/lite-xl/pull/1670)) + +* Fix `set_target_size` passing the wrong value to plugins + ([#1657](https://github.com/lite-xl/lite-xl/pull/1657)) + +* Limit `system.{sleep,wait_event}` to `timeouts >= 0` + ([#1666](https://github.com/lite-xl/lite-xl/pull/1666)) + +* Fix running core.step when receiving an event while not waiting + ([#1667](https://github.com/lite-xl/lite-xl/pull/1667)) + +* Fix dirmonitor sorting issues + ([#1599](https://github.com/lite-xl/lite-xl/pull/1599)) + +* Scale mouse coordinates by window scale + ([#1630](https://github.com/lite-xl/lite-xl/pull/1630)) + +* Made coroutines make more sense, and fixed a bug + ([#1381](https://github.com/lite-xl/lite-xl/pull/1381)) + +* Fix selecting newlines with `find-replace:select-add-{next,all}` + ([#1608](https://github.com/lite-xl/lite-xl/pull/1608)) + +* Fix editing after undo not clearing the change id + ([#1574](https://github.com/lite-xl/lite-xl/pull/1574)) + +* Fix language_js regex constant detection + ([#1581](https://github.com/lite-xl/lite-xl/pull/1581)) + +* Fix patterns starting with `^` in tokenizer + ([#1645](https://github.com/lite-xl/lite-xl/pull/1645)) + +* Use x offset to define render command rect in rencache_draw_text + ([#1618](https://github.com/lite-xl/lite-xl/pull/1618)) + +* Improve font/color change detection in `language_md` + ([#1614](https://github.com/lite-xl/lite-xl/pull/1614)) + +* Allow long commands and envs on process_start + ([#1477](https://github.com/lite-xl/lite-xl/pull/1477)) + +* Fix typo in `drawwhitespace.lua` + +* Fix NagBar save failed message + ([#1678](https://github.com/lite-xl/lite-xl/pull/1678)) + +* Fix typo in `drawwhitespace.lua` + +* Add autocompletion to multicursor + ([#1394](https://github.com/lite-xl/lite-xl/pull/1394)) + +### Other Changes + +* Make api_require's nodes const + ([#1296](https://github.com/lite-xl/lite-xl/pull/1296)) + +* Don't set a value twice + ([#1306](https://github.com/lite-xl/lite-xl/pull/1306)) + +* Center title and version in emptyview + ([#1311](https://github.com/lite-xl/lite-xl/pull/1311)) + +* Use master branch for packaging plugins for addons release + +* Reorganize resources folder and add wasm target + ([#1244](https://github.com/lite-xl/lite-xl/pull/1244)) + +* Replace uses of SDL_Window with RenWindow + ([#1319](https://github.com/lite-xl/lite-xl/pull/1319)) + +* Update dummy dirmonitor method signature to match prototypes + +* Remove static libgcc from meson + ([#1290](https://github.com/lite-xl/lite-xl/pull/1290)) + +* Pass RenWindow by argument + ([#1321](https://github.com/lite-xl/lite-xl/pull/1321)) + +* Get rid of annoying forward slash on windows + ([#1345](https://github.com/lite-xl/lite-xl/pull/1345)) + +* Improve plugins config table handling + ([#1356](https://github.com/lite-xl/lite-xl/pull/1356)) + +* Add manifest on Windows + ([#1405](https://github.com/lite-xl/lite-xl/pull/1405)) + +* Split Command struct into different structs for each command type + ([#1407](https://github.com/lite-xl/lite-xl/pull/1407)) + +* Move SetProcessDPIAware to manifests + ([#1413](https://github.com/lite-xl/lite-xl/pull/1413)) + +* Use clipping functions provided by SDL + ([#1426](https://github.com/lite-xl/lite-xl/pull/1426)) + +* Aggregate SDL_Surfaces and their scale in RenSurface + ([#1429](https://github.com/lite-xl/lite-xl/pull/1429)) + +* Disable trimwhitespace and drawwhitespace via their configs + ([#1446](https://github.com/lite-xl/lite-xl/pull/1446)) + +* Bump dependency versions + ([#1434](https://github.com/lite-xl/lite-xl/pull/1434)) + +* Improvements to cross-compilation + ([#1458](https://github.com/lite-xl/lite-xl/pull/1458)) + +* Move native plugin API header into include/ + ([#1440](https://github.com/lite-xl/lite-xl/pull/1440)) + +* Build releases with Ubuntu 18.04 container + ([#1460](https://github.com/lite-xl/lite-xl/pull/1460)) + +* Update GitHub Actions dependencies + +* Make all parameters for set_window_hit_test optional in documentation + +* Attach command buffer to Renderer Window + ([#1472](https://github.com/lite-xl/lite-xl/pull/1472)) + +* Fix comment typo in object.lua + ([#1541](https://github.com/lite-xl/lite-xl/pull/1541)) + +* Allow setting custom glyphset size + ([#1542](https://github.com/lite-xl/lite-xl/pull/1542)) + +* Use FreeType header names in renderer.c + ([#1554](https://github.com/lite-xl/lite-xl/pull/1554)) + +* Add documentation for core.common + ([#1510](https://github.com/lite-xl/lite-xl/pull/1510)) + +* Document missing parameter for system.path_compare + ([#1566](https://github.com/lite-xl/lite-xl/pull/1566)) + +* Add documentation for core.command + ([#1564](https://github.com/lite-xl/lite-xl/pull/1564)) + +* Update the *Installing prebuild* section in README.md + ([#1548](https://github.com/lite-xl/lite-xl/pull/1548)) + +* Update README.md to remove previously installed files + prior to installing a new version + +* Use lite-xl Build Box to build releases + ([#1571](https://github.com/lite-xl/lite-xl/pull/1571)) + +* Use Lua wrap by default + ([#1481](https://github.com/lite-xl/lite-xl/pull/1481)) + +* Add documentation for contextmenu + ([#1567](https://github.com/lite-xl/lite-xl/pull/1567)) + +* Use dmgbuild to create DMGs + ([#1664](https://github.com/lite-xl/lite-xl/pull/1664)) + +* Un-hardcode lua subproject detection and update dependencies + ([#1676](https://github.com/lite-xl/lite-xl/pull/1676)) + +* Make license time-independent + ([#1655](https://github.com/lite-xl/lite-xl/pull/1655)) + ## [2.1.1] - 2022-12-29 ### New Features @@ -1004,6 +1422,7 @@ A new global variable `USERDIR` is exposed to point to the user's directory. - subpixel font rendering with gamma correction +[2.1.2]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.2 [2.1.1]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.1 [2.1.0]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.0 [2.0.5]: https://github.com/lite-xl/lite-xl/releases/tag/v2.0.5 From 2ce8c58bea7b5c0e0cd692ab52e3bbacb04fb41e Mon Sep 17 00:00:00 2001 From: vqn <85911372+vqns@users.noreply.github.com> Date: Sat, 13 Jan 2024 13:49:26 +0100 Subject: [PATCH 138/148] Fix doc:create-cursor-previous/next-line with tabs (#1697) * use DocView.translate to split cursor on previous/next line * use dv.doc instead of doc() --- data/core/commands/doc.lua | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index 1155ac26..d697e663 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -93,11 +93,14 @@ local function cut_or_copy(delete) system.set_clipboard(full_text) end -local function split_cursor(direction) +local function split_cursor(dv, direction) local new_cursors = {} - for _, line1, col1 in doc():get_selections() do - if line1 + direction >= 1 and line1 + direction <= #doc().lines then - table.insert(new_cursors, { line1 + direction, col1 }) + local dv_translate = direction < 0 + and DocView.translate.previous_line + or DocView.translate.next_line + for _, line1, col1 in dv.doc:get_selections() do + if line1 + direction >= 1 and line1 + direction <= #dv.doc.lines then + table.insert(new_cursors, { dv_translate(dv.doc, line1, col1, dv) }) end end -- add selections in the order that will leave the "last" added one as doc.last_selection @@ -107,7 +110,7 @@ local function split_cursor(direction) end for i = start, stop, direction do local v = new_cursors[i] - doc():add_selection(v[1], v[2]) + dv.doc:add_selection(v[1], v[2]) end core.blink_reset() end @@ -621,12 +624,12 @@ local commands = { end, ["doc:create-cursor-previous-line"] = function(dv) - split_cursor(-1) + split_cursor(dv, -1) dv.doc:merge_cursors() end, ["doc:create-cursor-next-line"] = function(dv) - split_cursor(1) + split_cursor(dv, 1) dv.doc:merge_cursors() end From 4ae92ae128fcaefb098edb8123acb0d136e19e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chlo=C3=A9=20Vulquin?= Date: Sat, 20 Jan 2024 01:02:46 +0100 Subject: [PATCH 139/148] Memory fixes (#1705) * fix: free-before-init in renwin_init_surface when using sdl renderer `ren->rensurface.surface` presupposes zero-initialized rensurface. Rensurface was not actually zero-initialized. It is now. * fix: heap buffer overflow in process_env_free `process_env_free` presupposed that it was null-terminated. Pass length to free instead. * use calloc instead of memset for zero-init Co-authored-by: Guldoman --------- Co-authored-by: Guldoman --- src/api/process.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/process.c b/src/api/process.c index 66f27536..7b41135d 100644 --- a/src/api/process.c +++ b/src/api/process.c @@ -560,12 +560,12 @@ static int process_env_add(process_env_t *env_list, size_t *env_len, const char } -static void process_env_free(process_env_t *list) { +static void process_env_free(process_env_t *list, size_t list_len) { if (!*list) return; #ifdef _WIN32 free(*list); #else - for (size_t i = 0; (*list)[i]; i++) free((*list)[i]); + for (size_t i = 0; i < list_len; i++) free((*list)[i]); free(*list); #endif *list = NULL; @@ -830,7 +830,7 @@ static int process_start(lua_State* L) { } } process_arglist_free(&arglist); - process_env_free(&env_vars); + process_env_free(&env_vars, env_vars_len); if (retval == -1) return lua_error(L); From e353c5322a5957790561df1972c20a9acf178c20 Mon Sep 17 00:00:00 2001 From: Fiji <156847941+FijiHasGithub@users.noreply.github.com> Date: Sat, 20 Jan 2024 00:04:49 +0000 Subject: [PATCH 140/148] Improve number highlighting for python syntax highlighting (#1704) * Improve number highlighting for python syntax highlighting Adds support for octal and binary representation, as well uppercase characters (X, B and O) * add underscore and negative hex/oct/bin value support * Removed | from pattern --- data/plugins/language_python.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/plugins/language_python.lua b/data/plugins/language_python.lua index 743e990a..220ddd54 100644 --- a/data/plugins/language_python.lua +++ b/data/plugins/language_python.lua @@ -16,8 +16,8 @@ syntax.add { { pattern = { "[ruU]?'''", "'''", '\\' }, type = "string" }, { pattern = { '[ruU]?"', '"', '\\' }, type = "string" }, { pattern = { "[ruU]?'", "'", '\\' }, type = "string" }, - { pattern = "0x[%da-fA-F]+", type = "number" }, - { pattern = "-?%d+[%d%.eE]*", type = "number" }, + { pattern = "-?0[xboXBO][%da-fA-F_]+",type = "number" }, + { pattern = "-?%d+[%d%.eE_]*", type = "number" }, { pattern = "-?%.?%d+", type = "number" }, { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, { pattern = "[%a_][%w_]*%f[(]", type = "function" }, From df12a5dde68ce8b0c3405504ea800b5a648529c4 Mon Sep 17 00:00:00 2001 From: vqn <85911372+vqns@users.noreply.github.com> Date: Sat, 20 Jan 2024 01:19:12 +0100 Subject: [PATCH 141/148] reorder nagview options on doc:save error to be more consistent with other nagview confirmations (#1696) --- data/core/commands/doc.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/core/commands/doc.lua b/data/core/commands/doc.lua index d697e663..e841bb9c 100644 --- a/data/core/commands/doc.lua +++ b/data/core/commands/doc.lua @@ -44,8 +44,8 @@ local function save(filename) else core.error(err) core.nag_view:show("Saving failed", string.format("Couldn't save file \"%s\". Do you want to save to another location?", doc().filename), { - { text = "No", default_no = true }, - { text = "Yes", default_yes = true } + { text = "Yes", default_yes = true }, + { text = "No", default_no = true } }, function(item) if item.text == "Yes" then core.add_thread(function() From a389adbaf5ed5c5c14c8542fc5f59964cfbcbe3d Mon Sep 17 00:00:00 2001 From: vqn <85911372+vqns@users.noreply.github.com> Date: Sun, 21 Jan 2024 01:49:25 +0100 Subject: [PATCH 142/148] autoreload docs only if their filename matches an actual file (#1698) --- data/plugins/autoreload.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/plugins/autoreload.lua b/data/plugins/autoreload.lua index 8286d62f..f1ba6e0d 100644 --- a/data/plugins/autoreload.lua +++ b/data/plugins/autoreload.lua @@ -69,7 +69,7 @@ function dirwatch:check(change_callback, ...) for _, doc in ipairs(core.docs) do if doc.abs_filename and (dir == common.dirname(doc.abs_filename) or dir == doc.abs_filename) then local info = system.get_file_info(doc.filename or "") - if info and times[doc] ~= info.modified then + if info and info.type == "file" and times[doc] ~= info.modified then if not doc:is_dirty() and not config.plugins.autoreload.always_show_nagview then reload_doc(doc) else From bbc524ad82458fedff94a76dc84a9bf702513ba1 Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sun, 21 Jan 2024 10:18:13 +0800 Subject: [PATCH 143/148] language_js: support binary and octal representation (#1710) --- data/plugins/language_js.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/data/plugins/language_js.lua b/data/plugins/language_js.lua index 307aeecf..2eb38741 100644 --- a/data/plugins/language_js.lua +++ b/data/plugins/language_js.lua @@ -57,18 +57,18 @@ syntax.add { comment = "//", block_comment = { "/*", "*/" }, patterns = { - { pattern = "//.*", type = "comment" }, - { pattern = { "/%*", "%*/" }, type = "comment" }, + { pattern = "//.*", type = "comment" }, + { pattern = { "/%*", "%*/" }, type = "comment" }, { regex = regex_pattern, syntax = inner_regex_syntax, type = {"string", "string"} }, - { pattern = { '"', '"', '\\' }, type = "string" }, - { pattern = { "'", "'", '\\' }, type = "string" }, - { pattern = { "`", "`", '\\' }, type = "string" }, - { pattern = "0x[%da-fA-F_]+n?()%s*()/?", type = {"number", "normal", "operator"} }, - { pattern = "-?%d+[%d%.eE_n]*()%s*()/?", type = {"number", "normal", "operator"} }, - { pattern = "-?%.?%d+()%s*()/?", type = {"number", "normal", "operator"} }, - { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, - { pattern = "[%a_][%w_]*%f[(]", type = "function" }, - { pattern = "[%a_][%w_]*()%s*()/?", type = {"symbol", "normal", "operator"} }, + { pattern = { '"', '"', '\\' }, type = "string" }, + { pattern = { "'", "'", '\\' }, type = "string" }, + { pattern = { "`", "`", '\\' }, type = "string" }, + { pattern = "-?0[xXbBoO][%da-fA-F_]+n?()%s*()/?", type = {"number", "normal", "operator"} }, + { pattern = "-?%d+[%d%.eE_n]*()%s*()/?", type = {"number", "normal", "operator"} }, + { pattern = "-?%.?%d+()%s*()/?", type = {"number", "normal", "operator"} }, + { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, + { pattern = "[%a_][%w_]*%f[(]", type = "function" }, + { pattern = "[%a_][%w_]*()%s*()/?", type = {"symbol", "normal", "operator"} }, }, symbols = { ["async"] = "keyword", From b856dc371a9d2e2b7a1864c7b1a23bcc23270bee Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Sun, 21 Jan 2024 10:18:32 +0800 Subject: [PATCH 144/148] process: style changes (#1709) --- src/api/process.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/api/process.c b/src/api/process.c index 7b41135d..50cbd767 100644 --- a/src/api/process.c +++ b/src/api/process.c @@ -562,12 +562,11 @@ static int process_env_add(process_env_t *env_list, size_t *env_len, const char static void process_env_free(process_env_t *list, size_t list_len) { if (!*list) return; -#ifdef _WIN32 - free(*list); -#else - for (size_t i = 0; i < list_len; i++) free((*list)[i]); - free(*list); +#ifndef _WIN32 + for (size_t i = 0; i < list_len; i++) + free((*list)[i]); #endif + free(*list); *list = NULL; } From b4d750013dafef35a04f3c488367010f2a2d1ad6 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sun, 21 Jan 2024 14:59:52 +0800 Subject: [PATCH 145/148] changelog: update changelog for v2.1.3 --- changelog.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/changelog.md b/changelog.md index 7fecb1cb..4e51752a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,34 @@ # Changes Log +## [2.1.3-rc1] - 2024-01-21 + +This release addresses severe bugs not found in previous releases. + +### Fixes + +* Fix `doc:create-cursor-{previous,next}-line` with tabs + ([#1697](https://github.com/lite-xl/lite-xl/pull/1697)) + +* Fix heap buffer overflow and memory leaks in process and renderer API + ([#1705](https://github.com/lite-xl/lite-xl/pull/1705)) + +* Improve Python number syntax highlighting + ([#1704](https://github.com/lite-xl/lite-xl/pull/1704)) + +* Fix inconsistent NagView options on `doc:save` + ([#1696](https://github.com/lite-xl/lite-xl/pull/1696)) + +* Fix crashes with autoreload when files are deleted externally and replaced with a directory. + ([#1698](https://github.com/lite-xl/lite-xl/pull/1698)) + +* Improve JavaScript number syntax highlighting + ([#1710](https://github.com/lite-xl/lite-xl/pull/1710)) + +## Other Changes + +* Process API style changes + ([#1709](https://github.com/lite-xl/lite-xl/pull/1709)) + ## [2.1.2] - 2023-12-29 This release addresses some issues present in the previous release, @@ -1422,6 +1451,7 @@ A new global variable `USERDIR` is exposed to point to the user's directory. - subpixel font rendering with gamma correction +[2.1.3-rc1]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.3-rc1 [2.1.2]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.2 [2.1.1]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.1 [2.1.0]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.0 From 328ed55f83460b5f3936213f44df110d2dc6ecc2 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Sun, 21 Jan 2024 15:12:00 +0800 Subject: [PATCH 146/148] update version in metadata --- .github/workflows/release.yml | 2 +- meson.build | 2 +- resources/linux/org.lite_xl.lite_xl.appdata.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e788ab1f..65fb450c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ on: inputs: version: description: Release Version - default: v2.1.2 + default: v2.1.3 required: true jobs: diff --git a/meson.build b/meson.build index 72dc0588..3f88be37 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('lite-xl', ['c'], - version : '2.1.2', + version : '2.1.3', license : 'MIT', meson_version : '>= 0.56', default_options : [ diff --git a/resources/linux/org.lite_xl.lite_xl.appdata.xml b/resources/linux/org.lite_xl.lite_xl.appdata.xml index 761e4e68..1e9c87e9 100644 --- a/resources/linux/org.lite_xl.lite_xl.appdata.xml +++ b/resources/linux/org.lite_xl.lite_xl.appdata.xml @@ -29,6 +29,6 @@ - + From caf30574ed55b7afbb8d933fce8e0510e8747cea Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Mon, 29 Jan 2024 07:42:20 +0800 Subject: [PATCH 147/148] changelog: fix formatting issue and release date --- changelog.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 4e51752a..a488016d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,6 @@ # Changes Log -## [2.1.3-rc1] - 2024-01-21 +## [2.1.3] - 2024-01-29 This release addresses severe bugs not found in previous releases. @@ -24,7 +24,7 @@ This release addresses severe bugs not found in previous releases. * Improve JavaScript number syntax highlighting ([#1710](https://github.com/lite-xl/lite-xl/pull/1710)) -## Other Changes +### Other Changes * Process API style changes ([#1709](https://github.com/lite-xl/lite-xl/pull/1709)) @@ -1451,7 +1451,7 @@ A new global variable `USERDIR` is exposed to point to the user's directory. - subpixel font rendering with gamma correction -[2.1.3-rc1]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.3-rc1 +[2.1.3]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.3 [2.1.2]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.2 [2.1.1]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.1 [2.1.0]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.0 From c6a7ff98b021985c9185ba5ab1644b9dff6be565 Mon Sep 17 00:00:00 2001 From: takase1121 <20792268+takase1121@users.noreply.github.com> Date: Mon, 29 Jan 2024 07:47:49 +0800 Subject: [PATCH 148/148] appstream: update release date --- resources/linux/org.lite_xl.lite_xl.appdata.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/linux/org.lite_xl.lite_xl.appdata.xml b/resources/linux/org.lite_xl.lite_xl.appdata.xml index 1e9c87e9..d0c9f38c 100644 --- a/resources/linux/org.lite_xl.lite_xl.appdata.xml +++ b/resources/linux/org.lite_xl.lite_xl.appdata.xml @@ -29,6 +29,6 @@ - +