- [NEW] Updatada la versió de Lua a 5.5.0

- [FIX] Afegits defines de Lua per a cada SO
This commit is contained in:
2026-05-16 08:52:39 +02:00
parent 672f4278e0
commit ae0ff0bd62
61 changed files with 7062 additions and 4393 deletions
+176 -80
View File
@@ -22,15 +22,7 @@
#include "lauxlib.h"
#include "lualib.h"
/*
** LUA_IGMARK is a mark to ignore all before it when building the
** luaopen_ function name.
*/
#if !defined (LUA_IGMARK)
#define LUA_IGMARK "-"
#endif
#include "llimits.h"
/*
@@ -67,11 +59,8 @@ static const char *const CLIBS = "_CLIBS";
#define setprogdir(L) ((void)0)
/*
** Special type equivalent to '(void*)' for functions in gcc
** (to suppress warnings when converting function pointers)
*/
typedef void (*voidf)(void);
/* cast void* to a Lua function */
#define cast_Lfunc(p) cast(lua_CFunction, cast_func(p))
/*
@@ -104,26 +93,13 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
#if defined(LUA_USE_DLOPEN) /* { */
/*
** {========================================================================
** This is an implementation of loadlib based on the dlfcn interface.
** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
** as an emulation layer on top of native functions.
** This is an implementation of loadlib based on the dlfcn interface,
** which is available in all POSIX systems.
** =========================================================================
*/
#include <dlfcn.h>
/*
** Macro to convert pointer-to-void* to pointer-to-function. This cast
** is undefined according to ISO C, but POSIX assumes that it works.
** (The '__extension__' in gnu compilers is only to avoid warnings.)
*/
#if defined(__GNUC__)
#define cast_func(p) (__extension__ (lua_CFunction)(p))
#else
#define cast_func(p) ((lua_CFunction)(p))
#endif
static void lsys_unloadlib (void *lib) {
dlclose(lib);
@@ -139,7 +115,7 @@ static void *lsys_load (lua_State *L, const char *path, int seeglb) {
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = cast_func(dlsym(lib, sym));
lua_CFunction f = cast_Lfunc(dlsym(lib, sym));
if (l_unlikely(f == NULL))
lua_pushstring(L, dlerror());
return f;
@@ -215,7 +191,7 @@ static void *lsys_load (lua_State *L, const char *path, int seeglb) {
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)(voidf)GetProcAddress((HMODULE)lib, sym);
lua_CFunction f = cast_Lfunc(GetProcAddress((HMODULE)lib, sym));
if (f == NULL) pusherror(L);
return f;
}
@@ -292,7 +268,8 @@ static int noenv (lua_State *L) {
/*
** Set a path
** Set a path. (If using the default path, assume it is a string
** literal in C and create it as an external string.)
*/
static void setpath (lua_State *L, const char *fieldname,
const char *envname,
@@ -303,7 +280,7 @@ static void setpath (lua_State *L, const char *fieldname,
if (path == NULL) /* no versioned environment variable? */
path = getenv(envname); /* try unversioned name */
if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, dft); /* use default */
lua_pushexternalstring(L, dft, strlen(dft), NULL, NULL); /* use default */
else if ((dftmark = strstr(path, LUA_PATH_SEP LUA_PATH_SEP)) == NULL)
lua_pushstring(L, path); /* nothing to change */
else { /* path contains a ";;": insert default path in its place */
@@ -311,13 +288,13 @@ static void setpath (lua_State *L, const char *fieldname,
luaL_Buffer b;
luaL_buffinit(L, &b);
if (path < dftmark) { /* is there a prefix before ';;'? */
luaL_addlstring(&b, path, dftmark - path); /* add it */
luaL_addlstring(&b, path, ct_diff2sz(dftmark - path)); /* add it */
luaL_addchar(&b, *LUA_PATH_SEP);
}
luaL_addstring(&b, dft); /* add default */
if (dftmark < path + len - 2) { /* is there a suffix after ';;'? */
luaL_addchar(&b, *LUA_PATH_SEP);
luaL_addlstring(&b, dftmark + 2, (path + len - 2) - dftmark);
luaL_addlstring(&b, dftmark + 2, ct_diff2sz((path + len - 2) - dftmark));
}
luaL_pushresult(&b);
}
@@ -329,6 +306,16 @@ static void setpath (lua_State *L, const char *fieldname,
/* }================================================================== */
/*
** External strings created by DLLs may need the DLL code to be
** deallocated. This implies that a DLL can only be unloaded after all
** its strings were deallocated. To ensure that, we create a 'library
** string' to represent each DLL, and when this string is deallocated
** it closes its corresponding DLL.
** (The string itself is irrelevant; its userdata is the DLL pointer.)
*/
/*
** return registry.CLIBS[path]
*/
@@ -343,34 +330,41 @@ static void *checkclib (lua_State *L, const char *path) {
/*
** registry.CLIBS[path] = plib -- for queries
** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
** Deallocate function for library strings.
** Unload the DLL associated with the string being deallocated.
*/
static void addtoclib (lua_State *L, const char *path, void *plib) {
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
lua_pushlightuserdata(L, plib);
lua_pushvalue(L, -1);
lua_setfield(L, -3, path); /* CLIBS[path] = plib */
lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
lua_pop(L, 1); /* pop CLIBS table */
static void *freelib (void *ud, void *ptr, size_t osize, size_t nsize) {
/* string itself is irrelevant and static */
(void)ptr; (void)osize; (void)nsize;
lsys_unloadlib(ud); /* unload library represented by the string */
return NULL;
}
/*
** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
** handles in list CLIBS
** Create a library string that, when deallocated, will unload 'plib'
*/
static int gctm (lua_State *L) {
lua_Integer n = luaL_len(L, 1);
for (; n >= 1; n--) { /* for each handle, in reverse order */
lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
lsys_unloadlib(lua_touserdata(L, -1));
lua_pop(L, 1); /* pop handle */
}
return 0;
static void createlibstr (lua_State *L, void *plib) {
/* common content for all library strings */
static const char dummy[] = "01234567890";
lua_pushexternalstring(L, dummy, sizeof(dummy) - 1, freelib, plib);
}
/*
** registry.CLIBS[path] = plib -- for queries.
** Also create a reference to strlib, so that the library string will
** only be collected when registry.CLIBS is collected.
*/
static void addtoclib (lua_State *L, const char *path, void *plib) {
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
lua_pushlightuserdata(L, plib);
lua_setfield(L, -2, path); /* CLIBS[path] = plib */
createlibstr(L, plib);
luaL_ref(L, -2); /* keep library string in CLIBS */
lua_pop(L, 1); /* pop CLIBS table */
}
/* error codes for 'lookforfunc' */
#define ERRLIB 1
@@ -384,8 +378,8 @@ static int gctm (lua_State *L) {
** Then, if 'sym' is '*', return true (as library has been loaded).
** Otherwise, look for symbol 'sym' in the library and push a
** C function with that symbol.
** Return 0 and 'true' or a function in the stack; in case of
** errors, return an error code and an error message in the stack.
** Return 0 with 'true' or a function in the stack; in case of
** errors, return an error code with an error message in the stack.
*/
static int lookforfunc (lua_State *L, const char *path, const char *sym) {
void *reg = checkclib(L, path); /* check loaded C libraries */
@@ -566,7 +560,7 @@ static int loadfunc (lua_State *L, const char *filename, const char *modname) {
mark = strchr(modname, *LUA_IGMARK);
if (mark) {
int stat;
openfunc = lua_pushlstring(L, modname, mark - modname);
openfunc = lua_pushlstring(L, modname, ct_diff2sz(mark - modname));
openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc);
stat = lookforfunc(L, filename, openfunc);
if (stat != ERRFUNC) return stat;
@@ -591,7 +585,7 @@ static int searcher_Croot (lua_State *L) {
const char *p = strchr(name, '.');
int stat;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name);
lua_pushlstring(L, name, ct_diff2sz(p - name));
filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* root not found */
if ((stat = loadfunc(L, filename, name)) != 0) {
@@ -629,12 +623,12 @@ static void findloader (lua_State *L, const char *name) {
!= LUA_TTABLE))
luaL_error(L, "'package.searchers' must be a table");
luaL_buffinit(L, &msg);
luaL_addstring(&msg, "\n\t"); /* error-message prefix for first message */
/* iterate over available searchers to find a loader */
for (i = 1; ; i++) {
luaL_addstring(&msg, "\n\t"); /* error-message prefix */
if (l_unlikely(lua_rawgeti(L, 3, i) == LUA_TNIL)) { /* no more searchers? */
lua_pop(L, 1); /* remove nil */
luaL_buffsub(&msg, 2); /* remove prefix */
luaL_buffsub(&msg, 2); /* remove last prefix */
luaL_pushresult(&msg); /* create error message */
luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
}
@@ -645,17 +639,126 @@ static void findloader (lua_State *L, const char *name) {
else if (lua_isstring(L, -2)) { /* searcher returned error message? */
lua_pop(L, 1); /* remove extra return */
luaL_addvalue(&msg); /* concatenate error message */
luaL_addstring(&msg, "\n\t"); /* prefix for next message */
}
else { /* no error message */
else /* no error message */
lua_pop(L, 2); /* remove both returns */
luaL_buffsub(&msg, 2); /* remove prefix */
}
}
}
// [RZC 12/03/2026] ==================================
// Soport per a rutes relatives i absolutes
//
static void resolve_module_name(lua_State *L, char *out, size_t outsz) {
const char *req = luaL_checkstring(L, 1);
// 1. RUTA ABSOLUTA: empieza por ':'
if (req[0] == ':') {
strncpy(out, req + 1, outsz - 1);
out[outsz - 1] = '\0';
return;
}
// 2. Obtener módulo llamador
lua_Debug ar;
if (!lua_getstack(L, 1, &ar)) {
// No hay llamador → usar nombre tal cual
strncpy(out, req, outsz - 1);
out[outsz - 1] = '\0';
return;
}
lua_getinfo(L, "S", &ar);
// ar.source contiene algo como "@ia.test" o "@main"
const char *src = ar.source;
if (!src) {
// No viene de archivo → usar nombre tal cual
strncpy(out, req, outsz - 1);
out[outsz - 1] = '\0';
return;
}
// Quitar '@'
//src++;
// 3. Extraer directorio del módulo llamador
// Ej: "ia.tools.other" → "ia.tools"
char caller[256];
strncpy(caller, src, sizeof(caller) - 1);
caller[sizeof(caller) - 1] = '\0';
char *lastdot = strrchr(caller, '.');
if (lastdot)
*lastdot = '\0'; // dejar solo el directorio
else
caller[0] = '\0'; // está en la raíz
// 4. RUTA RELATIVA HACIA ARRIBA: empieza por ".."
if (req[0] == '.' && req[1] == '.') {
// Contar cuántos '.' consecutivos hay
int up = 0;
while (req[up] == '.')
up++;
// up = número de puntos → niveles a subir
// Ej: "..test" → up=2 → subir 1 nivel
// "...main" → up=3 → subir 2 niveles
int levels = up - 1;
// Copiar caller a buffer temporal
char temp[256];
strncpy(temp, caller, sizeof(temp) - 1);
temp[sizeof(temp) - 1] = '\0';
// Subir niveles
for (int i = 0; i < levels; i++) {
char *p = strrchr(temp, '.');
if (p)
*p = '\0';
else {
temp[0] = '\0';
break;
}
}
// Concatenar lo que queda después de los puntos
const char *rest = req + up;
if (temp[0] == '\0') {
// Hemos llegado a la raíz
strncpy(out, rest, outsz - 1);
} else {
snprintf(out, outsz, "%s.%s", temp, rest);
}
out[outsz - 1] = '\0';
return;
}
// 5. RUTA RELATIVA NORMAL (no empieza por ':' ni por '..')
if (caller[0] == '\0') {
// Estamos en la raíz
strncpy(out, req, outsz - 1);
} else {
snprintf(out, outsz, "%s.%s", caller, req);
}
out[outsz - 1] = '\0';
}
// ===================================================
static int ll_require (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
// [RZC 12/03/2026] ==================================
// Soport per a rutes relatives i absolutes
//
//const char *name = luaL_checkstring(L, 1);
char resolved[256];
resolve_module_name(L, resolved, sizeof(resolved));
const char *name = resolved;
// ===================================================
lua_settop(L, 1); /* LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_getfield(L, 2, name); /* LOADED[name] */
@@ -708,8 +811,13 @@ static const luaL_Reg ll_funcs[] = {
static void createsearcherstable (lua_State *L) {
static const lua_CFunction searchers[] =
{searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
static const lua_CFunction searchers[] = {
searcher_preload,
searcher_Lua,
searcher_C,
searcher_Croot,
NULL
};
int i;
/* create 'searchers' table */
lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
@@ -723,21 +831,9 @@ static void createsearcherstable (lua_State *L) {
}
/*
** create table CLIBS to keep track of loaded C libraries,
** setting a finalizer to close all libraries when closing state.
*/
static void createclibstable (lua_State *L) {
luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */
lua_createtable(L, 0, 1); /* create metatable for CLIBS */
lua_pushcfunction(L, gctm);
lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
lua_setmetatable(L, -2);
}
LUAMOD_API int luaopen_package (lua_State *L) {
createclibstable(L);
luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */
lua_pop(L, 1); /* will not use it now */
luaL_newlib(L, pk_funcs); /* create 'package' table */
createsearcherstable(L);
/* set paths */