Files
hizzlekizzle d2e771806a Rename .gitlab-ci.yaml to .gitlab-ci.yml
this was breaking the CI process -_-

simplify libretro makefile (#1)

only build the components needed by libretro

default to building with GCC

see if this can clear some CI hurdles

let runners override toolchain

libretro: build fixes (#2)

libretro: more apple build fixes (#4)

libretro: apple build fixes (#5)

buildfix for iOS/tvOS

libretro: frontend VFS support + Android/Windows/libnx build fixes (#3)

* libretro: route all file access through the frontend VFS

RetroArch can hand the core paths that don't exist on the real
filesystem - the common case being Android SAF content:// URIs, which
only the frontend can open. The core sets need_fullpath, so it opens the
content itself and every one of those loads currently fails.

All of the core's file I/O goes through utf8::ifstream/utf8::ofstream, so
routing those two through a VFS-backed streambuf covers ROMs, patches,
firmware, battery saves, save states, screenshots and recordings:

 - Utilities/VfsFile.{h,cpp}: VfsStreamBuf, a std::streambuf on top of
   retro_vfs_interface with a stdio fallback for when no frontend VFS is
   available, plus VfsIo helpers for stat/mkdir/opendir/remove/rename.
   Note that RetroArch's seek() returns 0 rather than the new offset, so
   the position is always read back with tell().
 - UTF8Util.h: in LIBRETRO builds utf8::ifstream/ofstream are backed by
   VfsStreamBuf (the _WIN32 wide-path classes stay for other builds).
 - retro_set_environment asks for VFS v3 and falls back to v2, so the
   directory calls are used when the frontend has them.
 - FolderUtilities uses the VFS for CreateFolder/GetFolders/
   GetFilesInFolder when v3 is available, std::filesystem otherwise.
 - ZipWriter builds archives in memory and writes them out through the
   stream layer - miniz's file API goes straight to stdio.
 - The remaining direct std::ifstream/std::ofstream/rename/remove calls
   in libretro.cpp and sha1.cpp now go through the same layer.

Verified with a harness that only accepts saf://-prefixed paths (a core
still on stdio fails to load): GB and SNES content loads, and the
RecentGames archive is written back through the VFS. A second harness
that refuses GET_VFS_INTERFACE checks the stdio fallback.

* libretro: fix the Android, Windows and libnx builds

Android (No rule to make target '.../Core/APU.cpp'): Libretro/jni/
Android.mk pulled its file list from Libretro/Makefile.common, a
leftover from the Mesen 1 libretro port that lists sources this tree
doesn't have. Android.mk now derives the sources the same way
Makefile.libretro does (and builds as C++17, not C++11); the two stale
Mesen 1 makefiles are removed.

Windows x64: two failures.
 - Lua/unixdgram.c needs sys/un.h. The unix-domain luasocket modules
   (unix.c, unixdgram.c, unixstream.c, serial.c) aren't registered by the
   core and aren't in the MSVC project either, so they're excluded.
 - The core is cross-compiled from Linux, so uname reported Linux and the
   build produced a .so with ELF-only link flags. The OS is now taken
   from the target triple, and the Windows build gets --no-undefined plus
   the winsock/UPnP import libraries.

libnx: the job builds with platform=libnx and then moves
mesen2_libretro_libnx.a, but Makefile.libretro had no such target, so it
built a host .so and the job died on the move. It now includes
switch_rules, compiles with the devkitA64 flags and archives a static
library. Untested - this needs a CI run on the libnx image to confirm the
core itself builds for the Switch.

Also fixes the compiler detection: `$(CXX) --version` matched 'gcc|g++'
by name, so a plain `make -f Makefile.libretro` (CXX=c++) took the clang
path and passed -flto=thin to GCC. It now looks for clang instead.

* libretro: use _wfopen_s in the MSVC build

The Mesen solution compiles with C4996 as an error, so the deprecated
_wfopen broke the standalone Windows build. The stdio fallback now has a
single open helper that uses _wfopen_s on MSVC.

* libretro: keep the core changes behind LIBRETRO, restore the old makefiles

Review feedback on libretro/MesenCE#3: the changes outside the libretro
glue should be conditional so this stays a soft fork, and the deleted
files should come back.

Everything the VFS work touches in shared code is now behind #ifdef
LIBRETRO - the WaveRecorder stream member, sha1's file hash, ZipWriter's
archive writing and FolderUtilities' directory calls all build exactly as
before without it. VfsFile.{h,cpp} is a libretro-only translation unit now
(empty otherwise), so it is out of Utilities.vcxproj again; Makefile.libretro
and Android.mk pick it up by globbing.

The macro is LIBRETRO, which is what Makefile.libretro and Android.mk
define, rather than __LIBRETRO__.

Libretro/Makefile and Libretro/Makefile.common are restored. Android.mk no
longer includes Makefile.common, so the stale Mesen 1 file list is only
dead weight rather than a broken build.

Re-verified after the change: linux-x64 core builds, the saf:// harness
loads GB and SNES content and writes the RecentGames archive through the
VFS, and the no-VFS harness still loads content through stdio.

* libretro: confine the VFS to the libretro layer

Review feedback on libretro/MesenCE#3: keep the VFS out of the core and
wrap the core's existing file access instead.

VfsFile.{h,cpp} moves to Libretro/, so it is not part of Utilities at all
any more. The interception point is utf8::ifstream/ofstream in
UTF8Util.h - the one place the core already routes file access through -
which is the only file in Core/ or Utilities/ that mentions the VFS.

The four sites that used to bypass utf8:: now go through it, which drops
their #ifdef LIBRETRO entirely (and incidentally fixes non-ASCII paths on
Windows, where utf8:: is what the rest of the codebase already uses):

- sha1.cpp opened a raw std::ifstream
- WaveRecorder held a std::ofstream, now a utf8::ofstream opened in place
  rather than move-assigned
- ZipWriter used miniz's stdio API; it now drives mz_zip_writer_init with
  a write callback backed by an ofstream, and reads added files through
  an ifstream. Still streamed, so no in-memory archive
- FolderUtilities keeps three guarded early-returns; the directory walk
  itself moved to VfsIo::GetEntries/CreateFolderIfSupported, which return
  false when the frontend has no v3 folder calls so the core falls back
  to std::filesystem

Makefile.libretro and Android.mk compile Libretro/VfsFile.cpp explicitly.

libretro: fix the Windows and libnx buildbot jobs (#6)

* libretro: lowercase the Windows headers for the MinGW cross-build

The buildbot's libretro-build-windows-x64 job is an MXE MinGW cross-build
running on Linux, where the include lookup is case-sensitive. mingw-w64
ships these headers all-lowercase, so <Windows.h> and <Ws2tcpip.h> are not
found and the job dies on Utilities/PlatformUtilities.cpp:

  fatal error: Windows.h: No such file or directory

MSVC is unaffected either way, since the Windows filesystem matches the
name regardless of case.

UTF8Util.cpp keeps its <Windows.h>: that include sits behind #ifdef
_MSC_VER, so the MinGW build never reaches it.

* libretro: don't require IN6ADDR_ANY_INIT on libnx

libretro-build-libnx-aarch64 dies on luasocket:

  Lua/inet.c:374:39: error: 'IN6ADDR_ANY_INIT' undeclared

devkitA64's newlib declares in6_addr, sockaddr_in6 and AF_INET6 - the
rest of the IPv6 code around it compiles - but not that macro. Fall back
to zeroing the address, which is what the wildcard address is by
definition and does not depend on how in6_addr is laid out.

libretro doesn't need upnp mapping

hopefully fix win64 builds

remove LUAOBJ from libnx

hopefully get it building on CI

fix typo in ifdef

libretro: fix the remaining Windows and libnx buildbot failures (#7)

* libretro: link winmm on Windows

PlatformUtilities asks for a 1ms timer resolution while a game runs, and
nothing in LIBS provides timeBeginPeriod/timeEndPeriod, so the MXE link ends
on __imp_timeBeginPeriod / __imp_timeEndPeriod. Those two are the only
symbols left unresolved in the buildbot's windows-x64 job.

* libretro: define _DEFAULT_SOURCE on libnx

Utilities/Socket.cpp does not compile there: u_long, fd_set, FD_ZERO,
FD_SET, select and struct timeval are all undeclared. They are all in
newlib, behind __MISC_VISIBLE and __BSD_VISIBLE - and newlib sets both from
_DEFAULT_SOURCE alone, which it auto-defines only when __STRICT_ANSI__ is
absent. CXXFLAGS passes --std=c++17, which defines it.

glibc turns _DEFAULT_SOURCE on whatever the dialect, so the same source
builds everywhere else and only the Switch job sees this.

re-add LUAOBJ to libnx

libretro: fix the windows-x64 link and get libnx past Lua (#8)

* libretro: give the VFS streams a key function

The windows-x64 job links with -flto and stops on multiple definitions of
the vtable, VTT and construction vtables for utf8::ifstream and
utf8::ofstream, one pair per translation unit that includes UTF8Util.h:

  BsxCart.o: multiple definition of `vtable for utf8::ifstream';
  libretro.o: first defined here

std::istream and std::ostream inherit virtually, so a class derived from
them gets construction vtables and a VTT as well as its own vtable. With no
key function all of it is emitted everywhere into .gnu.linkonce comdats, and
on PE/COFF the group keys come out inconsistent between objects - the same
section is keyed on the vtable in one and on the construction vtable in
another - so the linker keeps both instead of folding them.

Declaring the destructors in the header and defining them in the .cpp makes
those the key functions, so one object emits the lot. The VFS streams are the
only classes here that derive from a virtual base, which is why this is the
job that noticed.

* libretro: build libnx as gnu++17 instead of patching around __STRICT_ANSI__

declarations back for Utilities/Socket.cpp. That was the narrower of the two
options and it only covered newlib: the job now reaches Lua and stops there,
because gcc's own limits.h leaves LLONG_MAX undefined in C++ mode when
__STRICT_ANSI__ is set, and luaconf.h reads that as "no long long":

  Lua/luaconf.h:572: error: #error "Compiler does not support 'long long'.
    Use option '-DLUA_32BITS' or '-DLUA_C89_NUMBERS'"

Both come from the same place, so take the other option instead. MESENFLAGS
lands after the global --std=c++17 in CXXFLAGS, so this stays scoped to
libnx; every other target keeps the dialect it had.

* Delete mesen2_libretro.so

libretro: give libnx the ipv6_mreq luasocket needs (#9)

libretro-build-libnx-aarch64 is the last red job on the buildbot, and it
dies in luasocket:

  Lua/options.c: In function 'opt_ip6_setmembership':
  Lua/options.c:399:22: error: storage size of 'val' isn't known
    399 |     struct ipv6_mreq val;

devkitA64's newlib declares in6_addr, sockaddr_in6 and the
IPV6_ADD_MEMBERSHIP / IPV6_DROP_MEMBERSHIP constants - the two callers a
few lines up compile, and the IN6ADDR_ANY_INIT fallback in inet.c already
leans on in6_addr being there - but it never declares the struct those
two options take.

There is no macro to test a struct tag for, so the shim keys off
__SWITCH__, and it declares luasocket_ipv6_mreq rather than filling in
struct ipv6_mreq so that a devkitA64 that grows the real one later cannot
collide with it. socket.h is where it goes because options.c is built on
every platform and only reaches usocket.h off Windows.

The layout is the one RFC 3493 fixes; checked against glibc, both are 20
bytes with the fields at 0 and 16, so the buffer handed to setsockopt()
is unchanged. Whether the Switch network stack honours IPv6 multicast
joins at runtime is a separate question - this only stops the option from
breaking the build for every other libnx user.

set core option to default to 44.1 khz

this was making everything 55 FPS instead of 60

libretro: give libnx the LLONG_MAX luaconf.h expects (#10)

With the ipv6_mreq shim from #9 in, the libnx job gets past Lua/options.c
and dies further along, in the first C++ translation unit that pulls in
lua.hpp:

  In file included from Lua/lua.h:16,
                   from Lua/lua.hpp:6,
                   from Core/Debugger/LuaCallHelper.h:3,
                   from Core/Debugger/LuaCallHelper.cpp:2:
  Lua/luaconf.h:572:2: error: #error "Compiler does not support 'long long'."

luaconf.h includes <limits.h> itself and then gates its LUA_INT_LONGLONG
branch on LLONG_MAX. devkitA64's newlib does not make that macro visible to
C++ translation units, so the branch falls through to the #error - while the
C files in the same build, which the -std=gnu++17 in CFLAGS does not apply
to, see it and compile.

The error suggests LUA_32BITS or LUA_C89_NUMBERS, but both change Lua's
integer type, and only on the Switch. GCC always predefines
__LONG_LONG_MAX__, so fill LLONG_MAX, LLONG_MIN and ULLONG_MAX from it
instead, guarded on __SWITCH__ and on the macro actually being absent.

Checked against glibc's limits.h: all three expressions compare equal to the
real LLONG_MAX, LLONG_MIN and ULLONG_MAX, and luaconf.h still parses from
both C and C++ with the block inert off-Switch.
2026-08-29 10:21:13 -05:00

818 lines
22 KiB
C

/*
** $Id: luaconf.h $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
#ifndef luaconf_h
#define luaconf_h
#include <limits.h>
#include <stddef.h>
/*
** devkitA64's newlib does not make LLONG_MAX visible to C++ translation units,
** so the LUA_INT_LONGLONG branch further down falls through to its
** "Compiler does not support 'long long'" #error - even though the compiler
** supports it perfectly well, and even though the C files in this same build
** see the macro and compile. GCC always predefines __LONG_LONG_MAX__, so fill
** the three macros from it rather than take the error's advice and drop Lua to
** LUA_32BITS, which would change the integer type on the Switch only.
*/
#if defined(__SWITCH__) && !defined(LLONG_MAX) && defined(__LONG_LONG_MAX__)
#define LLONG_MAX __LONG_LONG_MAX__
#define LLONG_MIN (-LLONG_MAX - 1LL)
#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
#endif
/*
** ===================================================================
** 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
#if defined(LUA_USE_IOS)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN
#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
/*
** LUA_IGMARK is a mark to ignore all after it when building the
** module name (e.g., used to build the luaopen_ function name).
** Typically, the suffix after the mark is the module version,
** as in "mod-v1.2.so".
*/
#define LUA_IGMARK "-"
/* }================================================================== */
/*
** {==================================================================
** 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 <stdint.h>
#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 <assert.h>
#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 and max(int)/2.)
*/
#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 initial 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
/* }================================================================== */
/* =================================================================== */
/*
** Local configuration. You can use this space to add your redefinitions
** without modifying the main part of the file.
*/
#endif