Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6f8c0f3
Added compat53 support and fixed bugged non-interactive mode
ItsMeForLua Jul 14, 2025
a604743
Delete et
ItsMeForLua Jul 14, 2025
3961c37
Added compat53 to init block: added .gitmodules init to install.sh
ItsMeForLua Jul 23, 2025
7c4b465
Added Jenkins files for local CI testing
ItsMeForLua Jul 23, 2025
bac1f1c
Fixing Jenkins Setup: Attempt2
ItsMeForLua Jul 23, 2025
4cae3c2
update the Jenkinsfile to explicitly tell the docker build command wh…
ItsMeForLua Jul 23, 2025
8e69247
This file defines the environment for the lush application: Attempt4
ItsMeForLua Jul 23, 2025
5666a23
Jenkins checkout step with the SubmoduleOption enabled: Attempt5
ItsMeForLua Jul 23, 2025
ad56a06
Add a simple shell command to manually initialize the submodules: att…
ItsMeForLua Jul 23, 2025
2215c76
Add diagnostics: attempt6a
ItsMeForLua Jul 23, 2025
9586722
named container to run the build, and then use docker cp to copy the …
ItsMeForLua Jul 23, 2025
5009299
Added liblua5.4-dev package for build
ItsMeForLua Jul 23, 2025
92c575c
Fixed the header path for compat: preload compat modules for lua with…
ItsMeForLua Jul 23, 2025
69001c1
Compat53 library uses the floor function, which is part of the C math…
ItsMeForLua Jul 23, 2025
8f1b021
src/lush.c ln:1500-1508: corrected the 'luaL' typos
ItsMeForLua Jul 23, 2025
35347be
Re-added luaL_openlibs(L); ln:1495
ItsMeForLua Jul 23, 2025
cfb49d6
Instead of copying the compiled files out and then mounting a volume …
ItsMeForLua Jul 23, 2025
eed4553
Ensure that the expected directory structure exists inside the contai…
ItsMeForLua Jul 23, 2025
e9c1fc6
Copying the ENTIRE subdirectory as expected: ln:27
ItsMeForLua Jul 23, 2025
e4b34ef
This final change corrects the test script to align with what the com…
ItsMeForLua Jul 23, 2025
a66d54c
Removed the problematic _ENV;compat53 DOES NOT provide lexical scopin…
ItsMeForLua Jul 23, 2025
7400ec4
luaopen_bit32 is called during initialization. This means the bit32 l…
ItsMeForLua Jul 23, 2025
1805298
- The premake5.lua file has been updated to include the LUA_COMPAT_BI…
ItsMeForLua Jul 23, 2025
b034e12
Removing the dependencies from lib/
ItsMeForLua Jul 23, 2025
da888fa
Ignore Jenkins home directory
ItsMeForLua Jul 23, 2025
e5ddafc
Re-added the lib/ directory: it is now empty
ItsMeForLua Jul 23, 2025
12a94cd
CRITICAL FOR TESTING: This copies the entire Jenkins workspace (inclu…
ItsMeForLua Jul 23, 2025
8d9b53f
CRITICAL ISSUE: Deleting lib/ files has introduced the issue of actua…
ItsMeForLua Jul 23, 2025
656a2e4
Attempt to patch CI pipeline: Dockerfile will now be selfcontained, a…
ItsMeForLua Jul 23, 2025
3f4e2c5
make was improperly being called inside the container on a project th…
ItsMeForLua Jul 23, 2025
e152028
Remove CI/CD pipeline files - moving to separate PR
ItsMeForLua Jul 23, 2025
49f3d15
build: Remove broken submodule configuration
ItsMeForLua Jul 23, 2025
4ac5583
Revert to old hashmap: fixed gitmodule index
ItsMeForLua Jul 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4


- name: Initialize submodules
run: git submodule update --init --recursive

- name: Set up dependencies
run: |
sudo apt-get update
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Makefile
*.make
*.log
bin
obj
.cache
.vscode/
.DS_Store
Thumbs.dbjenkins_home/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/compat53"]
path = lib/compat53
url = https://github.com/lunarmodules/lua-compat-5.3.git
3 changes: 3 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/bin/sh

echo "Initializing and updating submodules..."
git submodule update --init --recursive

# Function to install packages using apt (Debian/Ubuntu)
install_with_apt() {
sudo apt-get update
Expand Down
Empty file added lib/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions lib/compat53
Submodule compat53 added at dfd83b
18 changes: 15 additions & 3 deletions premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,33 @@ local lua_lib_path = "/usr/lib"
if os.findlib("lua5.4") then
lua_inc_path = "/usr/include/lua5.4"
lua_lib_path = "/usr/lib/5.4"
links({ "lua5.4" })
-- Readline for better interactive support, dl for dynamic loading, and m for the math library dependency
links({ "lua5.4", "readline", "dl", "m" })
else
links({ "lua" })
end

includedirs({ lua_inc_path, "lib/hashmap" })
includedirs({
lua_inc_path,
"lib/hashmap",
"lib/compat53/c-api"
})
libdirs({ lua_lib_path })

files({
"src/**.h",
"src/**.c",
"lib/hashmap/**.h",
"lib/hashmap/**.c",
"lib/compat53/c-api/compat-5.3.h",
"lib/compat53/c-api/compat-5.3.c",
"lib/compat53/lbitlib.c",
"lib/compat53/liolib.c",
"lib/compat53/lstrlib.c",
"lib/compat53/ltablib.c",
"lib/compat53/lutf8lib.c"
})
defines({ 'LUSH_VERSION="0.3.2"' })
defines({ 'LUSH_VERSION="0.3.2"', 'COMPAT53_PREFIX=""', 'LUA_COMPAT_BITLIB' })

filter("configurations:Debug")
defines({ "DEBUG" })
Expand Down
76 changes: 42 additions & 34 deletions src/lush.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#include "lua.h"
#include "lua_api.h"
#include "lualib.h"
#include "compat-5.3.h"
#include <asm-generic/ioctls.h>
#include <bits/time.h>
#include <ctype.h>
Expand All @@ -42,6 +43,10 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#include <time.h>
#include <unistd.h>

// Forward declare the open functions for the compat C modules we need to preload
int luaopen_bit32 (lua_State *L);
int luaopen_utf8 (lua_State *L);

#define BUFFER_SIZE 1024
#define MAX_GLOB 512

Expand Down Expand Up @@ -1485,13 +1490,26 @@ int main(int argc, char *argv[]) {
return 0;
}

// init lua state
lua_State *L = luaL_newstate();
if (!L) {
fprintf(stderr, "Failed to create Lua state\n");
return -1; // or handle appropriately
}
luaL_openlibs(L);

// --- Load compat modules and make them global ---
luaL_requiref(L, "bit32", luaopen_bit32, 1);
lua_pop(L, 1); // luaL_requiref leaves the module on the stack

luaL_requiref(L, "utf8", luaopen_utf8, 1);
lua_pop(L, 1);
// --- End pre-loading ---
lua_register_api(L);
lua_run_init(L);

// check if being run in command string mode
if (argc > 2 && strcmp(argv[1], "-c") == 0) {
// init Lua state
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_register_api(L);
lua_run_init(L);

// execute the command provided
char *command = argv[2];
Expand Down Expand Up @@ -1521,36 +1539,26 @@ int main(int argc, char *argv[]) {
return 0;
}

// init lua state
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_register_api(L);
lua_run_init(L);
// This is the corrected logic for running a script file non-interactively.
if (argc > 1) {
char *ext = strrchr(argv[1], '.');
if (ext && strcmp(ext, ".lua") == 0) {
const char *script_name = argv[1];
// The arguments for the script start at argv[2].
// We create a pointer to that part of the array.
char **script_args = (argc > 2) ? &argv[2] : NULL;

// if a lua function is passed on load run non-interactively
if (argc > 1) {
char *ext = strrchr(argv[1], '.');
if (ext) {
ext++;
if (strcmp(ext, "lua") == 0) {
int status = 0;
argv++;
char ***args = lush_split_args(argv, &status);

if (status == -1) {
fprintf(stderr, "lush: Expected end of quoted string\n");
} else if (lush_run(L, args, status) != 0) {
exit(1);
}
// Call the script loader directly with the script and its arguments.
if (lua_load_script(L, script_name, script_args) != 0) {
exit(1); // Exit if the script had an error
}

for (int i = 0; args[i]; i++) {
free(args[i]);
}
free(args);
return 0;
}
}
}
lua_close(L); // Clean up and exit
return 0;
}
}

// --- Interactive Shell Mode ---

// eat ^C in main
struct sigaction sa_int;
Expand Down Expand Up @@ -1617,4 +1625,4 @@ int main(int argc, char *argv[]) {
if (alt_shell != NULL)
free(alt_shell);
return 0;
}
}
60 changes: 60 additions & 0 deletions test/compat_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
-- test/compat_test.lua
-- A small test suite for the lua-compat-5.3 layer.
-- Can be run in two ways:
-- 1. ./lush test/compat_test.lua (runs all tests)
-- 2. ./lush test/compat_test.lua test_table_unpack (runs a single test)

local tests = {}

function tests.test_table_unpack()
print("--- Running test: table.unpack ---")
local my_table = { "a", "b", "c" }
-- The compat layer provides table.unpack for Lua 5.1.
local x, y, z = table.unpack(my_table)
assert(x == "a", "unpack failed for first element")
assert(y == "b", "unpack failed for second element")
assert(z == "c", "unpack failed for third element")
print("...SUCCESS!")
end

function tests.test_math_log_base()
print("--- Running test: math.log with base ---")
-- Lua 5.1's math.log only takes one argument. The compat layer adds the base.
local result = math.log(100, 10)
-- Use a small epsilon for floating point comparison
assert(math.abs(result - 2) < 1e-9, "math.log(100, 10) should be 2")
print("...SUCCESS!")
end

function tests.test_string_rep_separator()
print("--- Running test: string.rep with separator ---")
-- Lua 5.1's string.rep doesn't have the separator argument.
local result = string.rep("a", 3, "-")
assert(result == "a-a-a", "string.rep with separator failed, got: " .. tostring(result))
print("...SUCCESS!")
end


-- NOTE: The lush C host provides arguments in a global table named 'args', not 'arg'.
local test_to_run = args and args[1]

if test_to_run and tests[test_to_run] then
-- If a valid test name is provided, run only that test.
local success, err = pcall(tests[test_to_run])
if not success then
print("...FAILURE: " .. err)
end
elseif test_to_run then
-- If an invalid name is provided, show an error.
print("ERROR: Test function '" .. test_to_run .. "' not found.")
else
-- If no specific test is requested, run all of them.
print("--- Running all compatibility tests ---")
for name, func in pairs(tests) do
local success, err = pcall(func)
if not success then
print("...FAILURE on test '" .. name .. "': " .. err)
end
end
print("--- All tests complete ---")
end