diff options
41 files changed, 0 insertions, 8655 deletions
diff --git a/lib/compat53/.github/workflows/bit32-multi-arch-tests.yml b/lib/compat53/.github/workflows/bit32-multi-arch-tests.yml deleted file mode 100644 index aff29db..0000000 --- a/lib/compat53/.github/workflows/bit32-multi-arch-tests.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: bit32-multi-arch-tests -on: - push: - branches: ["master"] - pull_request: -jobs: - bit32-test: - runs-on: ubuntu-latest - name: bit32 tests on ${{ matrix.luaVersion }} ${{ matrix.arch }} - strategy: - fail-fast: false - matrix: - luaVersion: ["5.1.5", "5.4.1"] - luaRocksVersion: ["3.3.1"] - arch: ["armv7", "aarch64"] - steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 - id: lua-cache - with: - path: .install/${{ matrix.arch }}/lua-${{ matrix.luaVersion }} - key: lua-on-linux-${{ matrix.arch }}-${{ matrix.luaVersion }} - - uses: uraimo/run-on-arch-action@v2 - with: - arch: ${{ matrix.arch }} - distro: ubuntu_rolling - githubToken: ${{ github.token }} - setup: | - mkdir -p ".install/${{ matrix.arch }}" - install: | - apt-get update -q -y - apt-get install -q -y curl unzip build-essential libreadline-dev libncurses-dev clang - rm -rf /var/lib/apt/lists/* - run: | - v() { - echo -n -e "\033[36m" >&2 - echo -n "# $*" >&2 - echo -e "\033[0m" >&2 - "$@" - } - export CC=clang - if [ "${{ steps.lua-cache.outputs.cache-hit }}" != true ]; then - (set -o pipefail; cd ".install/${{ matrix.arch }}" && v curl --fail --silent --location "http://www.lua.org/ftp/lua-${{ matrix.luaVersion }}.tar.gz" | tar xzpf -) - (cd ".install/${{ matrix.arch }}/lua-${{ matrix.luaVersion }}" && v make linux) - fi - (cd ".install/${{ matrix.arch }}/lua-${{ matrix.luaVersion }}" && v make install) - (set -o pipefail; cd .install && v curl --fail --silent --location "http://luarocks.org/releases/luarocks-${{ matrix.luaRocksVersion }}.tar.gz" | tar xzpf -) - (cd ".install/luarocks-${{ matrix.luaRocksVersion }}" && v ./configure && v make bootstrap) - eval "$(luarocks path)" - v luarocks make rockspecs/bit32-scm-1.rockspec - v lua tests/test-bit32.lua - diff --git a/lib/compat53/.github/workflows/compat53-tests.yml b/lib/compat53/.github/workflows/compat53-tests.yml deleted file mode 100644 index 623837f..0000000 --- a/lib/compat53/.github/workflows/compat53-tests.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: compat53-tests -on: - push: - branches: ["master"] - pull_request: -jobs: - compat53-test: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - luaVersion: "lua=5.1" - compiler: gcc - external: false - - luaVersion: "lua=5.1" - compiler: gcc - external: true - - luaVersion: "lua=5.1" - compiler: g++ - external: true - - luaVersion: "lua=5.1" - compiler: clang - external: false - - luaVersion: "luajit=@v2.1 --compat=none" - compiler: gcc - external: false - - luaVersion: "luajit=@v2.1 --compat=none" - compiler: gcc - external: true - - luaVersion: "luajit=@v2.1 --compat=all" - compiler: gcc - external: false - - luaVersion: "luajit=@v2.1 --compat=all" - compiler: gcc - external: true - - luaVersion: "lua=5.2" - compiler: gcc - external: false - - luaVersion: "lua=5.2" - compiler: gcc - external: true - - luaVersion: "lua=5.2" - compiler: g++ - external: true - steps: - - uses: actions/checkout@v2 - - name: install Lua - run: | - sudo apt install libreadline-dev - pip3 install --user hererocks - ~/.local/bin/hererocks old --${{ matrix.luaVersion }} - test -e old/bin/lua || (cd old/bin && ln -s luajit* lua) - ~/.local/bin/hererocks new --lua=5.3 - - name: compile C modules - run: | - export CC=${{ matrix.compiler }} CFLAGS="-Wall -Wextra -Ic-api -O2 -fPIC" - export DEF="" SRC="" - if [ "${{ matrix.external }}" = true ]; then DEF="-DCOMPAT53_PREFIX=compat53" SRC="c-api/compat-5.3.c"; fi - ${CC} ${CFLAGS} -Iold/include ${DEF} -shared -o old/testmod.so tests/testmod.c ${SRC} - ${CC} ${CFLAGS} -Inew/include ${DEF} -shared -o new/testmod.so tests/testmod.c ${SRC} - ${CC} ${CFLAGS} -Iold/include ${DEF} -shared -o old/compat53.so ltablib.c lutf8lib.c lstrlib.c liolib.c ${SRC} - - name: run test scripts - run: | - (cd old && bin/lua ../tests/test.lua) > old.txt - (cd new && bin/lua ../tests/test.lua) > new.txt - - name: compare script output - run: diff old.txt new.txt || true - diff --git a/lib/compat53/.gitignore b/lib/compat53/.gitignore deleted file mode 100644 index 67c1b76..0000000 --- a/lib/compat53/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# generated files -*.so -*.dll -*.o -*.obj -HISTO - -# vim temporaries -.*.swp - diff --git a/lib/compat53/.travis.yml b/lib/compat53/.travis.yml deleted file mode 100644 index 44ae3a0..0000000 --- a/lib/compat53/.travis.yml +++ /dev/null @@ -1,47 +0,0 @@ -language: c -compiler: gcc - -sudo: false - -env: - - LUA="lua=5.1" - - LUA="lua=5.1" EXTERNAL=true - - LUA="lua=5.1" COMPILER="g++" - - LUA="lua=5.1" EXTERNAL=true COMPILER="g++" - - LUA="luajit=@v2.1 --compat=none" - - LUA="luajit=@v2.1 --compat=none" EXTERNAL=true - - LUA="luajit=@v2.1 --compat=all" - - LUA="luajit=@v2.1 --compat=all" EXTERNAL=true - - LUA="lua=5.2" - - LUA="lua=5.2" EXTERNAL=true - - LUA="lua=5.2" COMPILER="g++" - - LUA="lua=5.2" EXTERNAL=true COMPILER="g++" - -branches: - only: - - master - -git: - depth: 3 - -notifications: - email: false - -before_install: - - pip install --user hererocks - - hererocks old --$LUA - - test -e old/bin/lua || (cd old/bin && ln -s luajit* lua) - - hererocks new --lua=5.3 - -install: - - export CC="${COMPILER:-gcc}" DEF="" SRC="" CFLAGS="-Wall -Wextra -Ic-api -O2 -fPIC" - - if [ "x${EXTERNAL:-}" = xtrue ]; then DEF="-DCOMPAT53_PREFIX=compat53" SRC="c-api/compat-5.3.c"; fi - - ${CC} ${CFLAGS} -Iold/include ${DEF} -shared -o old/testmod.so tests/testmod.c ${SRC} - - ${CC} ${CFLAGS} -Inew/include ${DEF} -shared -o new/testmod.so tests/testmod.c ${SRC} - - gcc ${CFLAGS} -Iold/include ${DEF} -shared -o old/compat53.so ltablib.c lutf8lib.c lstrlib.c liolib.c ${SRC} - -script: - - (cd old && bin/lua ../tests/test.lua) > old.txt - - (cd new && bin/lua ../tests/test.lua) > new.txt - - diff old.txt new.txt || true - diff --git a/lib/compat53/LICENSE b/lib/compat53/LICENSE deleted file mode 100644 index 193ed12..0000000 --- a/lib/compat53/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (C) 1994-2020 Lua.org, PUC-Rio. -Copyright (C) 2013-2023 The Lua-Compat-5.3 authors. - -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. diff --git a/lib/compat53/README.md b/lib/compat53/README.md deleted file mode 100644 index 3ee6acf..0000000 --- a/lib/compat53/README.md +++ /dev/null @@ -1,243 +0,0 @@ -[](https://github.com/lunarmodules/lua-compat-5.3/actions?workflow=compat53-tests) -[](https://github.com/lunarmodules/lua-compat-5.3/actions?workflow=bit32-multi-arch-tests) - -# lua-compat-5.3 - -Lua-5.3-style APIs for Lua 5.2 and 5.1. - -## What is it - -This is a small module that aims to make it easier to write code -in a Lua-5.3-style that is compatible with Lua 5.1, Lua 5.2, and Lua -5.3. This does *not* make Lua 5.2 (or even Lua 5.1) entirely -compatible with Lua 5.3, but it brings the API closer to that of Lua -5.3. - -It includes: - -* _For writing Lua_: The Lua module `compat53`, which can be require'd - from Lua scripts and run in Lua 5.1, 5.2, and 5.3, including a - backport of the `utf8` module, the 5.3 `table` module, and the - string packing functions straight from the Lua 5.3 sources. -* _For writing C_: A C header and file which can be linked to your - Lua module written in C, providing some functions from the C API - of Lua 5.3 that do not exist in Lua 5.2 or 5.1, making it easier to - write C code that compiles with all three versions of liblua. - -## How to use it - -### Lua module - -```lua -require("compat53") -``` - -`compat53` makes changes to your global environment and does not return -a meaningful return value, so the usual idiom of storing the return of -`require` in a local variable makes no sense. - -When run under Lua 5.3+, this module does nothing. - -When run under Lua 5.2 or 5.1, it replaces some of your standard -functions and adds new ones to bring your environment closer to that -of Lua 5.3. It also tries to load the backported `utf8`, `table`, and -string packing modules automatically. If unsuccessful, pure Lua -versions of the new `table` functions are used as a fallback, and -[Roberto's struct library][1] is tried for string packing. - -#### Lua submodules - -```lua -local _ENV = require("compat53.module") -if setfenv then setfenv(1, _ENV) end -``` - -The `compat53.module` module does not modify the global environment, -and so it is safe to use in modules without affecting other Lua files. -It is supposed to be set as the current environment (see above), i.e. -cherry picking individual functions from this module is expressly -*not* supported!). Not all features are available when using this -module (e.g. yieldable (x)pcall support, string/file methods, etc.), -so it is recommended to use plain `require("compat53")` whenever -possible. - -### C code - -There are two ways of adding the C API compatibility functions/macros to -your project: -* If `COMPAT53_PREFIX` is *not* `#define`d, `compat-5.3.h` `#include`s - `compat-5.3.c`, and all functions are made `static`. You don't have to - compile/link/add `compat-5.3.c` yourself. This is useful for one-file - projects. -* If `COMPAT53_PREFIX` is `#define`d, all exported functions are renamed - behind the scenes using this prefix to avoid linker conflicts with other - code using this package. This doesn't change the way you call the - compatibility functions in your code. You have to compile and link - `compat-5.3.c` to your project yourself. You can change the way the - functions are exported using the `COMPAT53_API` macro (e.g. if you need - some `__declspec` magic). While it is technically possible to use - the "lua" prefix (and it looks better in the debugger), this is - discouraged because LuaJIT has started to implement its own Lua 5.2+ - C API functions, and with the "lua" prefix you'd violate the - one-definition rule with recent LuaJIT versions. - -## What's implemented - -### Lua - -* the `utf8` module backported from the Lua 5.3 sources -* `string.pack`, `string.packsize`, and `string.unpack` from the Lua - 5.3 sources or from the `struct` module. (`struct` is not 100% - compatible to Lua 5.3's string packing!) (See [here][4]) -* `math.maxinteger` and `math.mininteger`, `math.tointeger`, `math.type`, - and `math.ult` (see [here][5]) -* `assert` accepts non-string error messages -* `ipairs` respects `__index` metamethod -* `table.move` -* `table` library respects metamethods - -For Lua 5.1 additionally: -* `load` and `loadfile` accept `mode` and `env` parameters -* `table.pack` and `table.unpack` -* string patterns may contain embedded zeros (but see [here][6]) -* `string.rep` accepts `sep` argument -* `string.format` calls `tostring` on arguments for `%s` -* `math.log` accepts base argument -* `xpcall` takes additional arguments -* `pcall` and `xpcall` can execute functions that yield (see - [here][22] for a possible problem with `coroutine.running`) -* `pairs` respects `__pairs` metamethod (see [here][7]) -* `rawlen` (but `#` still doesn't respect `__len` for tables) -* `package.searchers` as alias for `package.loaders` -* `package.searchpath` (see [here][8]) -* `coroutine` functions dealing with the main coroutine (see - [here][22] for a possible problem with `coroutine.running`) -* `coroutine.create` accepts functions written in C -* return code of `os.execute` (see [here][9]) -* `io.write` and `file:write` return file handle -* `io.lines` and `file:lines` accept format arguments (like `io.read`) - (see [here][10] and [here][11]) -* `file:close` returns three results when a process is opened - with `io.popen` -* `debug.setmetatable` returns object -* `debug.getuservalue` (see [here][12]) -* `debug.setuservalue` (see [here][13]) - -### C - -* `lua_KContext` (see [here][14]) -* `lua_KFunction` (see [here][14]) -* `lua_dump` (extra `strip` parameter, ignored, see [here][15]) -* `lua_getextraspace` (limited compatibilitiy, see [here][24]) -* `lua_getfield` (return value) -* `lua_geti` and `lua_seti` -* `lua_getglobal` (return value) -* `lua_getmetafield` (return value) -* `lua_gettable` (return value) -* `lua_getuservalue` (limited compatibility, see [here][16]) -* `lua_setuservalue` (limited compatibility, see [here][17]) -* `lua_isinteger` -* `lua_numbertointeger` -* `lua_callk` and `lua_pcallk` (limited compatibility, see [here][14]) -* `lua_resume` -* `lua_rawget` and `lua_rawgeti` (return values) -* `lua_rawgetp` and `lua_rawsetp` -* `luaL_requiref` (now checks `package.loaded` first) -* `lua_rotate` -* `lua_stringtonumber` (see [here][18]) - -For Lua 5.1 additionally: -* `LUA_OK` -* `LUA_ERRGCMM` -* `LUA_OP*` macros for `lua_arith` and `lua_compare` -* `LUA_FILEHANDLE` -* `lua_Unsigned` -* `luaL_Stream` (limited compatibility, see [here][19]) -* `lua_absindex` -* `lua_arith` (see [here][20]) -* `lua_compare` -* `lua_len`, `lua_rawlen`, and `luaL_len` -* `lua_load` (mode argument) -* `lua_pushstring`, `lua_pushlstring` (return value) -* `lua_copy` -* `lua_pushglobaltable` -* `luaL_testudata` -* `luaL_setfuncs`, `luaL_newlibtable`, and `luaL_newlib` -* `luaL_setmetatable` -* `luaL_getsubtable` -* `luaL_traceback` -* `luaL_execresult` -* `luaL_fileresult` -* `luaL_loadbufferx` -* `luaL_loadfilex` -* `luaL_checkversion` (with empty body, only to avoid compile errors, - see [here][21]) -* `luaL_tolstring` -* `luaL_buffinitsize`, `luaL_prepbuffsize`, and `luaL_pushresultsize` - (see [here][22]) -* `lua_pushunsigned`, `lua_tounsignedx`, `lua_tounsigned`, - `luaL_checkunsigned`, `luaL_optunsigned`, if - `LUA_COMPAT_APIINTCASTS` is defined. - -## What's not implemented - -* bit operators -* integer division operator -* utf8 escape sequences -* 64 bit integers -* `coroutine.isyieldable` -* Lua 5.1: `_ENV`, `goto`, labels, ephemeron tables, etc. See - [`lua-compat-5.2`][2] for a detailed list. -* the following C API functions/macros: - * `lua_isyieldable` - * `lua_arith` (new operators missing) - * `lua_push(v)fstring` (new formats missing) - * `lua_upvalueid` (5.1) - * `lua_upvaluejoin` (5.1) - * `lua_version` (5.1) - * `lua_yieldk` (5.1) - -## See also - -* For Lua-5.2-style APIs under Lua 5.1, see [lua-compat-5.2][2], - which also is the basis for most of the code in this project. -* For Lua-5.1-style APIs under Lua 5.0, see [Compat-5.1][3] - -## Credits - -This package contains code written by: - -* [The Lua Team](http://www.lua.org) -* Philipp Janda ([@siffiejoe](http://github.com/siffiejoe)) -* Tomás Guisasola Gorham ([@tomasguisasola](http://github.com/tomasguisasola)) -* Hisham Muhammad ([@hishamhm](http://github.com/hishamhm)) -* Renato Maia ([@renatomaia](http://github.com/renatomaia)) -* [@ThePhD](http://github.com/ThePhD) -* [@Daurnimator](http://github.com/Daurnimator) - - - [1]: http://www.inf.puc-rio.br/~roberto/struct/ - [2]: http://github.com/lunarmodules/lua-compat-5.2/ - [3]: http://lunarmodules.org/compat/ - [4]: https://github.com/lunarmodules/lua-compat-5.3/wiki/string_packing - [5]: https://github.com/lunarmodules/lua-compat-5.3/wiki/math.type - [6]: https://github.com/lunarmodules/lua-compat-5.3/wiki/pattern_matching - [7]: https://github.com/lunarmodules/lua-compat-5.3/wiki/pairs - [8]: https://github.com/lunarmodules/lua-compat-5.3/wiki/package.searchpath - [9]: https://github.com/lunarmodules/lua-compat-5.3/wiki/os.execute - [10]: https://github.com/lunarmodules/lua-compat-5.3/wiki/io.lines - [11]: https://github.com/lunarmodules/lua-compat-5.3/wiki/file.lines - [12]: https://github.com/lunarmodules/lua-compat-5.3/wiki/debug.getuservalue - [13]: https://github.com/lunarmodules/lua-compat-5.3/wiki/debug.setuservalue - [14]: https://github.com/lunarmodules/lua-compat-5.3/wiki/yieldable_c_functions - [15]: https://github.com/lunarmodules/lua-compat-5.3/wiki/lua_dump - [16]: https://github.com/lunarmodules/lua-compat-5.3/wiki/lua_getuservalue - [17]: https://github.com/lunarmodules/lua-compat-5.3/wiki/lua_setuservalue - [18]: https://github.com/lunarmodules/lua-compat-5.3/wiki/lua_stringtonumber - [19]: https://github.com/lunarmodules/lua-compat-5.3/wiki/luaL_Stream - [20]: https://github.com/lunarmodules/lua-compat-5.3/wiki/lua_arith - [21]: https://github.com/lunarmodules/lua-compat-5.3/wiki/luaL_checkversion - [22]: https://github.com/lunarmodules/lua-compat-5.3/wiki/luaL_Buffer - [23]: https://github.com/lunarmodules/lua-compat-5.3/wiki/coroutine.running - [24]: https://github.com/lunarmodules/lua-compat-5.3/wiki/lua_getextraspace - diff --git a/lib/compat53/c-api/compat-5.3.c b/lib/compat53/c-api/compat-5.3.c deleted file mode 100644 index 1901a82..0000000 --- a/lib/compat53/c-api/compat-5.3.c +++ /dev/null @@ -1,957 +0,0 @@ -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <stdio.h> -#include "compat-5.3.h" - -/* don't compile it again if it already is included via compat53.h */ -#ifndef COMPAT53_C_ -#define COMPAT53_C_ - - - -/* definitions for Lua 5.1 only */ -#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 - -#ifndef COMPAT53_FOPEN_NO_LOCK -# if defined(_MSC_VER) -# define COMPAT53_FOPEN_NO_LOCK 1 -# else /* otherwise */ -# define COMPAT53_FOPEN_NO_LOCK 0 -# endif /* VC++ only so far */ -#endif /* No-lock fopen_s usage if possible */ - -#if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK -# include <share.h> -#endif /* VC++ _fsopen for share-allowed file read */ - -#ifndef COMPAT53_HAVE_STRERROR_R -# if (!defined(_WIN32)) && \ - ((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \ - (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) || \ - defined(__APPLE__)) -# define COMPAT53_HAVE_STRERROR_R 1 -# else /* none of the defines matched: define to 0 */ -# define COMPAT53_HAVE_STRERROR_R 0 -# endif /* have strerror_r of some form */ -#endif /* strerror_r */ - -#ifndef COMPAT53_HAVE_STRERROR_S -# if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \ - defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__) -# define COMPAT53_HAVE_STRERROR_S 1 -# else /* not VC++ or C11 */ -# define COMPAT53_HAVE_STRERROR_S 0 -# endif /* strerror_s from VC++ or C11 */ -#endif /* strerror_s */ - -#ifndef COMPAT53_LUA_FILE_BUFFER_SIZE -# define COMPAT53_LUA_FILE_BUFFER_SIZE 4096 -#endif /* Lua File Buffer Size */ - - -static char* compat53_strerror (int en, char* buff, size_t sz) { -#if COMPAT53_HAVE_STRERROR_R - /* use strerror_r here, because it's available on these specific platforms */ - if (sz > 0) { - buff[0] = '\0'; - /* we don't care whether the GNU version or the XSI version is used: */ - if (strerror_r(en, buff, sz)) { - /* Yes, we really DO want to ignore the return value! - * GCC makes that extra hard, not even a (void) cast will do. */ - } - if (buff[0] == '\0') { - /* Buffer is unchanged, so we probably have called GNU strerror_r which - * returned a static constant string. Chances are that strerror will - * return the same static constant string and therefore be thread-safe. */ - return strerror(en); - } - } - return buff; /* sz is 0 *or* strerror_r wrote into the buffer */ -#elif COMPAT53_HAVE_STRERROR_S - /* for MSVC and other C11 implementations, use strerror_s since it's - * provided by default by the libraries */ - strerror_s(buff, sz, en); - return buff; -#else - /* fallback, but strerror is not guaranteed to be threadsafe due to modifying - * errno itself and some impls not locking a static buffer for it ... but most - * known systems have threadsafe errno: this might only change if the locale - * is changed out from under someone while this function is being called */ - (void)buff; - (void)sz; - return strerror(en); -#endif -} - - -COMPAT53_API int lua_absindex (lua_State *L, int i) { - if (i < 0 && i > LUA_REGISTRYINDEX) - i += lua_gettop(L) + 1; - return i; -} - - -static void compat53_call_lua (lua_State *L, char const code[], size_t len, - int nargs, int nret) { - lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code); - if (lua_type(L, -1) != LUA_TFUNCTION) { - lua_pop(L, 1); - if (luaL_loadbuffer(L, code, len, "=none")) - lua_error(L); - lua_pushvalue(L, -1); - lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code); - } - lua_insert(L, -nargs-1); - lua_call(L, nargs, nret); -} - - -static const char compat53_arith_code[] = - "local op,a,b=...\n" - "if op==0 then return a+b\n" - "elseif op==1 then return a-b\n" - "elseif op==2 then return a*b\n" - "elseif op==3 then return a/b\n" - "elseif op==4 then return a%b\n" - "elseif op==5 then return a^b\n" - "elseif op==6 then return -a\n" - "end\n"; - -COMPAT53_API void lua_arith (lua_State *L, int op) { - if (op < LUA_OPADD || op > LUA_OPUNM) - luaL_error(L, "invalid 'op' argument for lua_arith"); - luaL_checkstack(L, 5, "not enough stack slots"); - if (op == LUA_OPUNM) - lua_pushvalue(L, -1); - lua_pushnumber(L, op); - lua_insert(L, -3); - compat53_call_lua(L, compat53_arith_code, - sizeof(compat53_arith_code)-1, 3, 1); -} - - -static const char compat53_compare_code[] = - "local a,b=...\n" - "return a<=b\n"; - -COMPAT53_API int lua_compare (lua_State *L, int idx1, int idx2, int op) { - int result = 0; - switch (op) { - case LUA_OPEQ: - return lua_equal(L, idx1, idx2); - case LUA_OPLT: - return lua_lessthan(L, idx1, idx2); - case LUA_OPLE: - luaL_checkstack(L, 5, "not enough stack slots"); - idx1 = lua_absindex(L, idx1); - idx2 = lua_absindex(L, idx2); - lua_pushvalue(L, idx1); - lua_pushvalue(L, idx2); - compat53_call_lua(L, compat53_compare_code, - sizeof(compat53_compare_code)-1, 2, 1); - result = lua_toboolean(L, -1); - lua_pop(L, 1); - return result; - default: - luaL_error(L, "invalid 'op' argument for lua_compare"); - } - return 0; -} - - -COMPAT53_API void lua_copy (lua_State *L, int from, int to) { - int abs_to = lua_absindex(L, to); - luaL_checkstack(L, 1, "not enough stack slots"); - lua_pushvalue(L, from); - lua_replace(L, abs_to); -} - - -COMPAT53_API void lua_len (lua_State *L, int i) { - switch (lua_type(L, i)) { - case LUA_TSTRING: - lua_pushnumber(L, (lua_Number)lua_objlen(L, i)); - break; - case LUA_TTABLE: - if (!luaL_callmeta(L, i, "__len")) - lua_pushnumber(L, (lua_Number)lua_objlen(L, i)); - break; - case LUA_TUSERDATA: - if (luaL_callmeta(L, i, "__len")) - break; - /* FALLTHROUGH */ - default: - luaL_error(L, "attempt to get length of a %s value", - lua_typename(L, lua_type(L, i))); - } -} - - -COMPAT53_API int lua_rawgetp (lua_State *L, int i, const void *p) { - int abs_i = lua_absindex(L, i); - lua_pushlightuserdata(L, (void*)p); - lua_rawget(L, abs_i); - return lua_type(L, -1); -} - -COMPAT53_API void lua_rawsetp (lua_State *L, int i, const void *p) { - int abs_i = lua_absindex(L, i); - luaL_checkstack(L, 1, "not enough stack slots"); - lua_pushlightuserdata(L, (void*)p); - lua_insert(L, -2); - lua_rawset(L, abs_i); -} - - -COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum) { - lua_Number n = lua_tonumber(L, i); - if (isnum != NULL) { - *isnum = (n != 0 || lua_isnumber(L, i)); - } - return n; -} - - -COMPAT53_API void luaL_checkversion (lua_State *L) { - (void)L; -} - - -COMPAT53_API void luaL_checkstack (lua_State *L, int sp, const char *msg) { - if (!lua_checkstack(L, sp+LUA_MINSTACK)) { - if (msg != NULL) - luaL_error(L, "stack overflow (%s)", msg); - else { - lua_pushliteral(L, "stack overflow"); - lua_error(L); - } - } -} - - -COMPAT53_API int luaL_getsubtable (lua_State *L, int i, const char *name) { - int abs_i = lua_absindex(L, i); - luaL_checkstack(L, 3, "not enough stack slots"); - lua_pushstring(L, name); - lua_gettable(L, abs_i); - if (lua_istable(L, -1)) - return 1; - lua_pop(L, 1); - lua_newtable(L); - lua_pushstring(L, name); - lua_pushvalue(L, -2); - lua_settable(L, abs_i); - return 0; -} - - -COMPAT53_API lua_Integer luaL_len (lua_State *L, int i) { - lua_Integer res = 0; - int isnum = 0; - luaL_checkstack(L, 1, "not enough stack slots"); - lua_len(L, i); - res = lua_tointegerx(L, -1, &isnum); - lua_pop(L, 1); - if (!isnum) - luaL_error(L, "object length is not an integer"); - return res; -} - - -COMPAT53_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { - luaL_checkstack(L, nup+1, "too many upvalues"); - for (; l->name != NULL; l++) { /* fill the table with given functions */ - int i; - lua_pushstring(L, l->name); - for (i = 0; i < nup; i++) /* copy upvalues to the top */ - lua_pushvalue(L, -(nup + 1)); - lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ - lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */ - } - lua_pop(L, nup); /* remove upvalues */ -} - - -COMPAT53_API void luaL_setmetatable (lua_State *L, const char *tname) { - luaL_checkstack(L, 1, "not enough stack slots"); - luaL_getmetatable(L, tname); - lua_setmetatable(L, -2); -} - - -COMPAT53_API void *luaL_testudata (lua_State *L, int i, const char *tname) { - void *p = lua_touserdata(L, i); - luaL_checkstack(L, 2, "not enough stack slots"); - if (p == NULL || !lua_getmetatable(L, i)) - return NULL; - else { - int res = 0; - luaL_getmetatable(L, tname); - res = lua_rawequal(L, -1, -2); - lua_pop(L, 2); - if (!res) - p = NULL; - } - return p; -} - - -static int compat53_countlevels (lua_State *L) { - lua_Debug ar; - int li = 1, le = 1; - /* find an upper bound */ - while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } - /* do a binary search */ - while (li < le) { - int m = (li + le)/2; - if (lua_getstack(L, m, &ar)) li = m + 1; - else le = m; - } - return le - 1; -} - -static int compat53_findfield (lua_State *L, int objidx, int level) { - if (level == 0 || !lua_istable(L, -1)) - return 0; /* not found */ - lua_pushnil(L); /* start 'next' loop */ - while (lua_next(L, -2)) { /* for each pair in table */ - if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ - if (lua_rawequal(L, objidx, -1)) { /* found object? */ - lua_pop(L, 1); /* remove value (but keep name) */ - return 1; - } - else if (compat53_findfield(L, objidx, level - 1)) { /* try recursively */ - lua_remove(L, -2); /* remove table (but keep name) */ - lua_pushliteral(L, "."); - lua_insert(L, -2); /* place '.' between the two names */ - lua_concat(L, 3); - return 1; - } - } - lua_pop(L, 1); /* remove value */ - } - return 0; /* not found */ -} - -static int compat53_pushglobalfuncname (lua_State *L, lua_Debug *ar) { - int top = lua_gettop(L); - lua_getinfo(L, "f", ar); /* push function */ - lua_pushvalue(L, LUA_GLOBALSINDEX); - if (compat53_findfield(L, top + 1, 2)) { - lua_copy(L, -1, top + 1); /* move name to proper place */ - lua_pop(L, 2); /* remove pushed values */ - return 1; - } - else { - lua_settop(L, top); /* remove function and global table */ - return 0; - } -} - -static void compat53_pushfuncname (lua_State *L, lua_Debug *ar) { - if (*ar->namewhat != '\0') /* is there a name? */ - lua_pushfstring(L, "function " LUA_QS, ar->name); - else if (*ar->what == 'm') /* main? */ - lua_pushliteral(L, "main chunk"); - else if (*ar->what == 'C') { - if (compat53_pushglobalfuncname(L, ar)) { - lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); - lua_remove(L, -2); /* remove name */ - } - else - lua_pushliteral(L, "?"); - } - else - lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); -} - -#define COMPAT53_LEVELS1 12 /* size of the first part of the stack */ -#define COMPAT53_LEVELS2 10 /* size of the second part of the stack */ - -COMPAT53_API void luaL_traceback (lua_State *L, lua_State *L1, - const char *msg, int level) { - lua_Debug ar; - int top = lua_gettop(L); - int numlevels = compat53_countlevels(L1); - int mark = (numlevels > COMPAT53_LEVELS1 + COMPAT53_LEVELS2) ? COMPAT53_LEVELS1 : 0; - if (msg) lua_pushfstring(L, "%s\n", msg); - lua_pushliteral(L, "stack traceback:"); - while (lua_getstack(L1, level++, &ar)) { - if (level == mark) { /* too many levels? */ - lua_pushliteral(L, "\n\t..."); /* add a '...' */ - level = numlevels - COMPAT53_LEVELS2; /* and skip to last ones */ - } - else { - lua_getinfo(L1, "Slnt", &ar); - lua_pushfstring(L, "\n\t%s:", ar.short_src); - if (ar.currentline > 0) - lua_pushfstring(L, "%d:", ar.currentline); - lua_pushliteral(L, " in "); - compat53_pushfuncname(L, &ar); - lua_concat(L, lua_gettop(L) - top); - } - } - lua_concat(L, lua_gettop(L) - top); -} - - -COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { - const char *serr = NULL; - int en = errno; /* calls to Lua API may change this value */ - char buf[512] = { 0 }; - if (stat) { - lua_pushboolean(L, 1); - return 1; - } - else { - lua_pushnil(L); - serr = compat53_strerror(en, buf, sizeof(buf)); - if (fname) - lua_pushfstring(L, "%s: %s", fname, serr); - else - lua_pushstring(L, serr); - lua_pushnumber(L, (lua_Number)en); - return 3; - } -} - - -static int compat53_checkmode (lua_State *L, const char *mode, const char *modename, int err) { - if (mode && strchr(mode, modename[0]) == NULL) { - lua_pushfstring(L, "attempt to load a %s chunk (mode is '%s')", modename, mode); - return err; - } - return LUA_OK; -} - - -typedef struct { - lua_Reader reader; - void *ud; - int has_peeked_data; - const char *peeked_data; - size_t peeked_data_size; -} compat53_reader_data; - - -static const char *compat53_reader (lua_State *L, void *ud, size_t *size) { - compat53_reader_data *data = (compat53_reader_data *)ud; - if (data->has_peeked_data) { - data->has_peeked_data = 0; - *size = data->peeked_data_size; - return data->peeked_data; - } else - return data->reader(L, data->ud, size); -} - - -COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char *source, const char *mode) { - int status = LUA_OK; - compat53_reader_data compat53_data = { 0, NULL, 1, 0, 0 }; - compat53_data.reader = reader; - compat53_data.ud = data; - compat53_data.peeked_data = reader(L, data, &(compat53_data.peeked_data_size)); - if (compat53_data.peeked_data && compat53_data.peeked_data_size && - compat53_data.peeked_data[0] == LUA_SIGNATURE[0]) /* binary file? */ - status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX); - else - status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX); - if (status != LUA_OK) - return status; - /* we need to call the original 5.1 version of lua_load! */ -#undef lua_load - return lua_load(L, compat53_reader, &compat53_data, source); -#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53) -} - - -typedef struct { - int n; /* number of pre-read characters */ - FILE *f; /* file being read */ - char buff[COMPAT53_LUA_FILE_BUFFER_SIZE]; /* area for reading file */ -} compat53_LoadF; - - -static const char *compat53_getF (lua_State *L, void *ud, size_t *size) { - compat53_LoadF *lf = (compat53_LoadF *)ud; - (void)L; /* not used */ - if (lf->n > 0) { /* are there pre-read characters to be read? */ - *size = lf->n; /* return them (chars already in buffer) */ - lf->n = 0; /* no more pre-read characters */ - } - else { /* read a block from file */ - /* 'fread' can return > 0 *and* set the EOF flag. If next call to - 'compat53_getF' called 'fread', it might still wait for user input. - The next check avoids this problem. */ - if (feof(lf->f)) return NULL; - *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ - } - return lf->buff; -} - - -static int compat53_errfile (lua_State *L, const char *what, int fnameindex) { - char buf[512] = {0}; - const char *serr = compat53_strerror(errno, buf, sizeof(buf)); - const char *filename = lua_tostring(L, fnameindex) + 1; - lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); - lua_remove(L, fnameindex); - return LUA_ERRFILE; -} - - -static int compat53_skipBOM (compat53_LoadF *lf) { - const char *p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */ - int c; - lf->n = 0; - do { - c = getc(lf->f); - if (c == EOF || c != *(const unsigned char *)p++) return c; - lf->buff[lf->n++] = (char)c; /* to be read by the parser */ - } while (*p != '\0'); - lf->n = 0; /* prefix matched; discard it */ - return getc(lf->f); /* return next character */ -} - - -/* -** reads the first character of file 'f' and skips an optional BOM mark -** in its beginning plus its first line if it starts with '#'. Returns -** true if it skipped the first line. In any case, '*cp' has the -** first "valid" character of the file (after the optional BOM and -** a first-line comment). -*/ -static int compat53_skipcomment (compat53_LoadF *lf, int *cp) { - int c = *cp = compat53_skipBOM(lf); - if (c == '#') { /* first line is a comment (Unix exec. file)? */ - do { /* skip first line */ - c = getc(lf->f); - } while (c != EOF && c != '\n'); - *cp = getc(lf->f); /* skip end-of-line, if present */ - return 1; /* there was a comment */ - } - else return 0; /* no comment */ -} - - -COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode) { - compat53_LoadF lf; - int status, readstatus; - int c; - int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ - if (filename == NULL) { - lua_pushliteral(L, "=stdin"); - lf.f = stdin; - } - else { - lua_pushfstring(L, "@%s", filename); -#if defined(_MSC_VER) - /* This code is here to stop a deprecation error that stops builds - * if a certain macro is defined. While normally not caring would - * be best, some header-only libraries and builds can't afford to - * dictate this to the user. A quick check shows that fopen_s this - * goes back to VS 2005, and _fsopen goes back to VS 2003 .NET, - * possibly even before that so we don't need to do any version - * number checks, since this has been there since forever. */ - - /* TO USER: if you want the behavior of typical fopen_s/fopen, - * which does lock the file on VC++, define the macro used below to 0 */ -#if COMPAT53_FOPEN_NO_LOCK - lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */ - if (lf.f == NULL) - return compat53_errfile(L, "open", fnameindex); -#else /* use default locking version */ - if (fopen_s(&lf.f, filename, "r") != 0) - return compat53_errfile(L, "open", fnameindex); -#endif /* Locking vs. No-locking fopen variants */ -#else - lf.f = fopen(filename, "r"); /* default stdlib doesn't forcefully lock files here */ - if (lf.f == NULL) return compat53_errfile(L, "open", fnameindex); -#endif - } - if (compat53_skipcomment(&lf, &c)) /* read initial portion */ - lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ - if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ -#if defined(_MSC_VER) - if (freopen_s(&lf.f, filename, "rb", lf.f) != 0) - return compat53_errfile(L, "reopen", fnameindex); -#else - lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ - if (lf.f == NULL) return compat53_errfile(L, "reopen", fnameindex); -#endif - compat53_skipcomment(&lf, &c); /* re-read initial portion */ - } - if (c != EOF) - lf.buff[lf.n++] = (char)c; /* 'c' is the first character of the stream */ - status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1), mode); - readstatus = ferror(lf.f); - if (filename) fclose(lf.f); /* close file (even in case of errors) */ - if (readstatus) { - lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ - return compat53_errfile(L, "read", fnameindex); - } - lua_remove(L, fnameindex); - return status; -} - - -COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) { - int status = LUA_OK; - if (sz > 0 && buff[0] == LUA_SIGNATURE[0]) { - status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX); - } - else { - status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX); - } - if (status != LUA_OK) - return status; - return luaL_loadbuffer(L, buff, sz, name); -} - - -#if !defined(l_inspectstat) && \ - (defined(unix) || defined(__unix) || defined(__unix__) || \ - defined(__TOS_AIX__) || defined(_SYSTYPE_BSD) || \ - (defined(__APPLE__) && defined(__MACH__))) -/* some form of unix; check feature macros in unistd.h for details */ -# include <unistd.h> -/* check posix version; the relevant include files and macros probably - * were available before 2001, but I'm not sure */ -# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L -# include <sys/wait.h> -# define l_inspectstat(stat,what) \ - if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ - else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } -# endif -#endif - -/* provide default (no-op) version */ -#if !defined(l_inspectstat) -# define l_inspectstat(stat,what) ((void)0) -#endif - - -COMPAT53_API int luaL_execresult (lua_State *L, int stat) { - const char *what = "exit"; - if (stat == -1) - return luaL_fileresult(L, 0, NULL); - else { - l_inspectstat(stat, what); - if (*what == 'e' && stat == 0) - lua_pushboolean(L, 1); - else - lua_pushnil(L); - lua_pushstring(L, what); - lua_pushinteger(L, stat); - return 3; - } -} - - -COMPAT53_API void luaL_buffinit (lua_State *L, luaL_Buffer_53 *B) { - /* make it crash if used via pointer to a 5.1-style luaL_Buffer */ - B->b.p = NULL; - B->b.L = NULL; - B->b.lvl = 0; - /* reuse the buffer from the 5.1-style luaL_Buffer though! */ - B->ptr = B->b.buffer; - B->capacity = LUAL_BUFFERSIZE; - B->nelems = 0; - B->L2 = L; -} - - -COMPAT53_API char *luaL_prepbuffsize (luaL_Buffer_53 *B, size_t s) { - if (B->capacity - B->nelems < s) { /* needs to grow */ - char* newptr = NULL; - size_t newcap = B->capacity * 2; - if (newcap - B->nelems < s) - newcap = B->nelems + s; - if (newcap < B->capacity) /* overflow */ - luaL_error(B->L2, "buffer too large"); - newptr = (char*)lua_newuserdata(B->L2, newcap); - memcpy(newptr, B->ptr, B->nelems); - if (B->ptr != B->b.buffer) - lua_replace(B->L2, -2); /* remove old buffer */ - B->ptr = newptr; - B->capacity = newcap; - } - return B->ptr+B->nelems; -} - - -COMPAT53_API void luaL_addlstring (luaL_Buffer_53 *B, const char *s, size_t l) { - memcpy(luaL_prepbuffsize(B, l), s, l); - luaL_addsize(B, l); -} - - -COMPAT53_API void luaL_addvalue (luaL_Buffer_53 *B) { - size_t len = 0; - const char *s = lua_tolstring(B->L2, -1, &len); - if (!s) - luaL_error(B->L2, "cannot convert value to string"); - if (B->ptr != B->b.buffer) - lua_insert(B->L2, -2); /* userdata buffer must be at stack top */ - luaL_addlstring(B, s, len); - lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1); -} - - -void luaL_pushresult (luaL_Buffer_53 *B) { - lua_pushlstring(B->L2, B->ptr, B->nelems); - if (B->ptr != B->b.buffer) - lua_replace(B->L2, -2); /* remove userdata buffer */ -} - - -#endif /* Lua 5.1 */ - - - -/* definitions for Lua 5.1 and Lua 5.2 */ -#if defined( LUA_VERSION_NUM ) && LUA_VERSION_NUM <= 502 - - -COMPAT53_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { -#undef lua_pushlstring - lua_pushlstring(L, len > 0 ? s : "", len); -#define lua_pushlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _pushlstring_53) - return lua_tostring(L, -1); -} - - -COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i) { - index = lua_absindex(L, index); - lua_pushinteger(L, i); - lua_gettable(L, index); - return lua_type(L, -1); -} - - -#ifndef LUA_EXTRASPACE -#define LUA_EXTRASPACE (sizeof(void*)) -#endif - -COMPAT53_API void *lua_getextraspace (lua_State *L) { - int is_main = 0; - void *ptr = NULL; - luaL_checkstack(L, 4, "not enough stack slots available"); - lua_pushliteral(L, "__compat53_extraspace"); - lua_pushvalue(L, -1); - lua_rawget(L, LUA_REGISTRYINDEX); - if (!lua_istable(L, -1)) { - lua_pop(L, 1); - lua_createtable(L, 0, 2); - lua_createtable(L, 0, 1); - lua_pushliteral(L, "k"); - lua_setfield(L, -2, "__mode"); - lua_setmetatable(L, -2); - lua_pushvalue(L, -2); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } - lua_replace(L, -2); - is_main = lua_pushthread(L); - lua_rawget(L, -2); - ptr = lua_touserdata(L, -1); - if (!ptr) { - lua_pop(L, 1); - ptr = lua_newuserdata(L, LUA_EXTRASPACE); - if (is_main) { - memset(ptr, '\0', LUA_EXTRASPACE); - lua_pushthread(L); - lua_pushvalue(L, -2); - lua_rawset(L, -4); - lua_pushboolean(L, 1); - lua_pushvalue(L, -2); - lua_rawset(L, -4); - } else { - void* mptr = NULL; - lua_pushboolean(L, 1); - lua_rawget(L, -3); - mptr = lua_touserdata(L, -1); - if (mptr) - memcpy(ptr, mptr, LUA_EXTRASPACE); - else - memset(ptr, '\0', LUA_EXTRASPACE); - lua_pop(L, 1); - lua_pushthread(L); - lua_pushvalue(L, -2); - lua_rawset(L, -4); - } - } - lua_pop(L, 2); - return ptr; -} - - -COMPAT53_API int lua_isinteger (lua_State *L, int index) { - if (lua_type(L, index) == LUA_TNUMBER) { - lua_Number n = lua_tonumber(L, index); - lua_Integer i = lua_tointeger(L, index); - if (i == n) - return 1; - } - return 0; -} - - -COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum) { - int ok = 0; - lua_Number n = lua_tonumberx(L, i, &ok); - if (ok) { - if (n == (lua_Integer)n) { - if (isnum) - *isnum = 1; - return (lua_Integer)n; - } - } - if (isnum) - *isnum = 0; - return 0; -} - - -static void compat53_reverse (lua_State *L, int a, int b) { - for (; a < b; ++a, --b) { - lua_pushvalue(L, a); - lua_pushvalue(L, b); - lua_replace(L, a); - lua_replace(L, b); - } -} - - -COMPAT53_API void lua_rotate (lua_State *L, int idx, int n) { - int n_elems = 0; - idx = lua_absindex(L, idx); - n_elems = lua_gettop(L)-idx+1; - if (n < 0) - n += n_elems; - if ( n > 0 && n < n_elems) { - luaL_checkstack(L, 2, "not enough stack slots available"); - n = n_elems - n; - compat53_reverse(L, idx, idx+n-1); - compat53_reverse(L, idx+n, idx+n_elems-1); - compat53_reverse(L, idx, idx+n_elems-1); - } -} - - -COMPAT53_API void lua_seti (lua_State *L, int index, lua_Integer i) { - luaL_checkstack(L, 1, "not enough stack slots available"); - index = lua_absindex(L, index); - lua_pushinteger(L, i); - lua_insert(L, -2); - lua_settable(L, index); -} - - -#if !defined(lua_str2number) -# define lua_str2number(s, p) strtod((s), (p)) -#endif - -COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s) { - char* endptr; - lua_Number n = lua_str2number(s, &endptr); - if (endptr != s) { - while (*endptr != '\0' && isspace((unsigned char)*endptr)) - ++endptr; - if (*endptr == '\0') { - lua_pushnumber(L, n); - return endptr - s + 1; - } - } - return 0; -} - - -COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { - if (!luaL_callmeta(L, idx, "__tostring")) { - int t = lua_type(L, idx), tt = 0; - char const* name = NULL; - switch (t) { - case LUA_TNIL: - lua_pushliteral(L, "nil"); - break; - case LUA_TSTRING: - case LUA_TNUMBER: - lua_pushvalue(L, idx); - break; - case LUA_TBOOLEAN: - if (lua_toboolean(L, idx)) - lua_pushliteral(L, "true"); - else - lua_pushliteral(L, "false"); - break; - default: - tt = luaL_getmetafield(L, idx, "__name"); - name = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : lua_typename(L, t); - lua_pushfstring(L, "%s: %p", name, lua_topointer(L, idx)); - if (tt != LUA_TNIL) - lua_replace(L, -2); - break; - } - } else { - if (!lua_isstring(L, -1)) - luaL_error(L, "'__tostring' must return a string"); - } - return lua_tolstring(L, -1, len); -} - - -COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, - lua_CFunction openf, int glb) { - luaL_checkstack(L, 3, "not enough stack slots available"); - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); - if (lua_getfield(L, -1, modname) == LUA_TNIL) { - lua_pop(L, 1); - lua_pushcfunction(L, openf); - lua_pushstring(L, modname); - lua_call(L, 1, 1); - lua_pushvalue(L, -1); - lua_setfield(L, -3, modname); - } - if (glb) { - lua_pushvalue(L, -1); - lua_setglobal(L, modname); - } - lua_replace(L, -2); -} - - -#endif /* Lua 5.1 and 5.2 */ - - -#endif /* COMPAT53_C_ */ - - -/********************************************************************* -* This file contains parts of Lua 5.2's and Lua 5.3's source code: -* -* Copyright (C) 1994-2014 Lua.org, PUC-Rio. -* -* 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. -*********************************************************************/ - diff --git a/lib/compat53/c-api/compat-5.3.h b/lib/compat53/c-api/compat-5.3.h deleted file mode 100644 index 6f66dad..0000000 --- a/lib/compat53/c-api/compat-5.3.h +++ /dev/null @@ -1,421 +0,0 @@ -#ifndef COMPAT53_H_ -#define COMPAT53_H_ - -#include <stddef.h> -#include <limits.h> -#include <string.h> -#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) -extern "C" { -#endif -#include <lua.h> -#include <lauxlib.h> -#include <lualib.h> -#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) -} -#endif - - -#undef COMPAT53_INCLUDE_SOURCE -#if defined(COMPAT53_PREFIX) -/* - change the symbol names of functions to avoid linker conflicts - * - compat-5.3.c needs to be compiled (and linked) separately - */ -# if !defined(COMPAT53_API) -# define COMPAT53_API extern -# endif -#else /* COMPAT53_PREFIX */ -/* - make all functions static and include the source. - * - compat-5.3.c doesn't need to be compiled (and linked) separately - */ -# define COMPAT53_PREFIX compat53 -# undef COMPAT53_API -# if defined(__GNUC__) || defined(__clang__) -# define COMPAT53_API __attribute__((__unused__)) static -# else -# define COMPAT53_API static -# endif -# define COMPAT53_INCLUDE_SOURCE -#endif /* COMPAT53_PREFIX */ - -#define COMPAT53_CONCAT_HELPER(a, b) a##b -#define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b) - - - -/* declarations for Lua 5.1 */ -#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 - -/* XXX not implemented: - * lua_arith (new operators) - * lua_upvalueid - * lua_upvaluejoin - * lua_version - * lua_yieldk - */ - -#ifndef LUA_OK -# define LUA_OK 0 -#endif -#ifndef LUA_OPADD -# define LUA_OPADD 0 -#endif -#ifndef LUA_OPSUB -# define LUA_OPSUB 1 -#endif -#ifndef LUA_OPMUL -# define LUA_OPMUL 2 -#endif -#ifndef LUA_OPDIV -# define LUA_OPDIV 3 -#endif -#ifndef LUA_OPMOD -# define LUA_OPMOD 4 -#endif -#ifndef LUA_OPPOW -# define LUA_OPPOW 5 -#endif -#ifndef LUA_OPUNM -# define LUA_OPUNM 6 -#endif -#ifndef LUA_OPEQ -# define LUA_OPEQ 0 -#endif -#ifndef LUA_OPLT -# define LUA_OPLT 1 -#endif -#ifndef LUA_OPLE -# define LUA_OPLE 2 -#endif - -/* LuaJIT/Lua 5.1 does not have the updated - * error codes for thread status/function returns (but some patched versions do) - * define it only if it's not found - */ -#if !defined(LUA_ERRGCMM) -/* Use + 2 because in some versions of Lua (Lua 5.1) - * LUA_ERRFILE is defined as (LUA_ERRERR+1) - * so we need to avoid it (LuaJIT might have something at this - * integer value too) - */ -# define LUA_ERRGCMM (LUA_ERRERR + 2) -#endif /* LUA_ERRGCMM define */ - -typedef size_t lua_Unsigned; - -typedef struct luaL_Buffer_53 { - luaL_Buffer b; /* make incorrect code crash! */ - char *ptr; - size_t nelems; - size_t capacity; - lua_State *L2; -} luaL_Buffer_53; -#define luaL_Buffer luaL_Buffer_53 - -/* In PUC-Rio 5.1, userdata is a simple FILE* - * In LuaJIT, it's a struct where the first member is a FILE* - * We can't support the `closef` member - */ -typedef struct luaL_Stream { - FILE *f; -} luaL_Stream; - -#define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex) -COMPAT53_API int lua_absindex (lua_State *L, int i); - -#define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith) -COMPAT53_API void lua_arith (lua_State *L, int op); - -#define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare) -COMPAT53_API int lua_compare (lua_State *L, int idx1, int idx2, int op); - -#define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy) -COMPAT53_API void lua_copy (lua_State *L, int from, int to); - -#define lua_getuservalue(L, i) \ - (lua_getfenv((L), (i)), lua_type((L), -1)) -#define lua_setuservalue(L, i) \ - (luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i))) - -#define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len) -COMPAT53_API void lua_len (lua_State *L, int i); - -#define lua_pushstring(L, s) \ - (lua_pushstring((L), (s)), lua_tostring((L), -1)) - -#ifndef luaL_newlibtable -# define luaL_newlibtable(L, l) \ - (lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1)) -#endif -#ifndef luaL_newlib -# define luaL_newlib(L, l) \ - (luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l))) -#endif - -#define lua_pushglobaltable(L) \ - lua_pushvalue((L), LUA_GLOBALSINDEX) - -#define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp) -COMPAT53_API int lua_rawgetp (lua_State *L, int i, const void *p); - -#define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp) -COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p); - -#define lua_rawlen(L, i) lua_objlen((L), (i)) - -#define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL) - -#define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx) -COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum); - -#define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion) -COMPAT53_API void luaL_checkversion (lua_State *L); - -#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53) -COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode); - -#define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex) -COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode); - -#define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx) -COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); - -#define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53) -COMPAT53_API void luaL_checkstack (lua_State *L, int sp, const char *msg); - -#define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable) -COMPAT53_API int luaL_getsubtable (lua_State* L, int i, const char *name); - -#define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len) -COMPAT53_API lua_Integer luaL_len (lua_State *L, int i); - -#define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs) -COMPAT53_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup); - -#define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable) -COMPAT53_API void luaL_setmetatable (lua_State *L, const char *tname); - -#define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata) -COMPAT53_API void *luaL_testudata (lua_State *L, int i, const char *tname); - -#define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback) -COMPAT53_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level); - -#define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult) -COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname); - -#define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult) -COMPAT53_API int luaL_execresult (lua_State *L, int stat); - -#define lua_callk(L, na, nr, ctx, cont) \ - ((void)(ctx), (void)(cont), lua_call((L), (na), (nr))) -#define lua_pcallk(L, na, nr, err, ctx, cont) \ - ((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err))) - -#define lua_resume(L, from, nargs) \ - ((void)(from), lua_resume((L), (nargs))) - -#define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53) -COMPAT53_API void luaL_buffinit (lua_State *L, luaL_Buffer_53 *B); - -#define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53) -COMPAT53_API char *luaL_prepbuffsize (luaL_Buffer_53 *B, size_t s); - -#define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53) -COMPAT53_API void luaL_addlstring (luaL_Buffer_53 *B, const char *s, size_t l); - -#define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53) -COMPAT53_API void luaL_addvalue (luaL_Buffer_53 *B); - -#define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53) -COMPAT53_API void luaL_pushresult (luaL_Buffer_53 *B); - -#undef luaL_buffinitsize -#define luaL_buffinitsize(L, B, s) \ - (luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s))) - -#undef luaL_prepbuffer -#define luaL_prepbuffer(B) \ - luaL_prepbuffsize((B), LUAL_BUFFERSIZE) - -#undef luaL_addchar -#define luaL_addchar(B, c) \ - ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \ - ((B)->ptr[(B)->nelems++] = (c))) - -#undef luaL_addsize -#define luaL_addsize(B, s) \ - ((B)->nelems += (s)) - -#undef luaL_addstring -#define luaL_addstring(B, s) \ - luaL_addlstring((B), (s), strlen((s))) - -#undef luaL_pushresultsize -#define luaL_pushresultsize(B, s) \ - (luaL_addsize((B), (s)), luaL_pushresult((B))) - -#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) -#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))) -#endif - -#endif /* Lua 5.1 only */ - - - -/* declarations for Lua 5.1 and 5.2 */ -#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502 - -typedef int lua_KContext; - -typedef int (*lua_KFunction)(lua_State *L, int status, lua_KContext ctx); - -#define lua_dump(L, w, d, s) \ - ((void)(s), lua_dump((L), (w), (d))) - -#define lua_getfield(L, i, k) \ - (lua_getfield((L), (i), (k)), lua_type((L), -1)) - -#define lua_gettable(L, i) \ - (lua_gettable((L), (i)), lua_type((L), -1)) - -#define lua_pushlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _pushlstring_53) -COMPAT53_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len); - -#define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti) -COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i); - -#define lua_getextraspace COMPAT53_CONCAT(COMPAT53_PREFIX, _getextraspace) -COMPAT53_API void *lua_getextraspace (lua_State *L); - -#define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger) -COMPAT53_API int lua_isinteger (lua_State *L, int index); - -#define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53) -COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum); - -#define lua_numbertointeger(n, p) \ - ((*(p) = (lua_Integer)(n)), 1) - -#define lua_rawget(L, i) \ - (lua_rawget((L), (i)), lua_type((L), -1)) - -#define lua_rawgeti(L, i, n) \ - (lua_rawgeti((L), (i), (n)), lua_type((L), -1)) - -#define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate) -COMPAT53_API void lua_rotate (lua_State *L, int idx, int n); - -#define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti) -COMPAT53_API void lua_seti (lua_State *L, int index, lua_Integer i); - -#define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber) -COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s); - -#define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring) -COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len); - -#define luaL_getmetafield(L, o, e) \ - (luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL) - -#define luaL_newmetatable(L, tn) \ - (luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0) - -#define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53) -COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, - lua_CFunction openf, int glb ); - -#endif /* Lua 5.1 and Lua 5.2 */ - - - -/* declarations for Lua 5.2 */ -#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502 - -/* XXX not implemented: - * lua_isyieldable - * lua_arith (new operators) - * lua_pushfstring (new formats) - */ - -#define lua_getglobal(L, n) \ - (lua_getglobal((L), (n)), lua_type((L), -1)) - -#define lua_getuservalue(L, i) \ - (lua_getuservalue((L), (i)), lua_type((L), -1)) - -#define lua_rawgetp(L, i, p) \ - (lua_rawgetp((L), (i), (p)), lua_type((L), -1)) - -#define LUA_KFUNCTION(_name) \ - static int (_name)(lua_State *L, int status, lua_KContext ctx); \ - static int (_name ## _52)(lua_State *L) { \ - lua_KContext ctx; \ - int status = lua_getctx(L, &ctx); \ - return (_name)(L, status, ctx); \ - } \ - static int (_name)(lua_State *L, int status, lua_KContext ctx) - -#define lua_pcallk(L, na, nr, err, ctx, cont) \ - lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52) - -#define lua_callk(L, na, nr, ctx, cont) \ - lua_callk((L), (na), (nr), (ctx), cont ## _52) - -#define lua_yieldk(L, nr, ctx, cont) \ - lua_yieldk((L), (nr), (ctx), cont ## _52) - -#ifdef lua_call -# undef lua_call -# define lua_call(L, na, nr) \ - (lua_callk)((L), (na), (nr), 0, NULL) -#endif - -#ifdef lua_pcall -# undef lua_pcall -# define lua_pcall(L, na, nr, err) \ - (lua_pcallk)((L), (na), (nr), (err), 0, NULL) -#endif - -#ifdef lua_yield -# undef lua_yield -# define lua_yield(L, nr) \ - (lua_yieldk)((L), (nr), 0, NULL) -#endif - -#endif /* Lua 5.2 only */ - - - -/* other Lua versions */ -#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504 - -# error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)" - -#endif /* other Lua versions except 5.1, 5.2, 5.3, and 5.4 */ - - - -/* helper macro for defining continuation functions (for every version - * *except* Lua 5.2) */ -#ifndef LUA_KFUNCTION -#define LUA_KFUNCTION(_name) \ - static int (_name)(lua_State *L, int status, lua_KContext ctx) -#endif - - -#if defined(COMPAT53_INCLUDE_SOURCE) -# include "compat-5.3.c" -#endif - - -#endif /* COMPAT53_H_ */ - diff --git a/lib/compat53/compat53/file_mt.lua b/lib/compat53/compat53/file_mt.lua deleted file mode 100644 index 6433619..0000000 --- a/lib/compat53/compat53/file_mt.lua +++ /dev/null @@ -1,71 +0,0 @@ -local lua_version = _VERSION:sub(-3) - -local M = {} - -local unpack = lua_version == "5.1" and unpack or table.unpack - -local function addasterisk(fmt) - if type(fmt) == "string" and fmt:sub(1, 1) ~= "*" then - return "*"..fmt - else - return fmt - end -end - -function M.update_file_meta(file_meta, is_luajit52) - - -- make '*' optional for file:read and file:lines - - local file_lines = file_meta.__index.lines - file_meta.__index.lines = function(self, ...) - local n = select('#', ...) - for i = 1, n do - local a = select(i, ...) - local b = addasterisk(a) - -- as an optimization we only allocate a table for the - -- modified format arguments when we have a '*' somewhere - if a ~= b then - local args = { ... } - args[i] = b - for j = i+1, n do - args[j] = addasterisk(args[j]) - end - return file_lines(self, unpack(args, 1, n)) - end - end - return file_lines(self, ...) - end - - local file_read = file_meta.__index.read - file_meta.__index.read = function(self, ...) - local n = select('#', ...) - for i = 1, n do - local a = select(i, ...) - local b = addasterisk(a) - -- as an optimization we only allocate a table for the - -- modified format arguments when we have a '*' somewhere - if a ~= b then - local args = { ... } - args[i] = b - for j = i+1, n do - args[j] = addasterisk(args[j]) - end - return file_read(self, unpack(args, 1, n)) - end - end - return file_read(self, ...) - end - - if not is_luajit52 then - local file_write = file_meta.__index.write - file_meta.__index.write = function(self, ...) - local ret, err = file_write(self, ...) - if ret then - return self - end - return ret, err - end - end -end - -return M diff --git a/lib/compat53/compat53/init.lua b/lib/compat53/compat53/init.lua deleted file mode 100644 index b507571..0000000 --- a/lib/compat53/compat53/init.lua +++ /dev/null @@ -1,325 +0,0 @@ -local lua_version = _VERSION:sub(-3) - - -if lua_version < "5.3" then - - local _G, pairs, require, select, type = - _G, pairs, require, select, type - local debug, io = debug, io - local unpack = lua_version == "5.1" and unpack or table.unpack - - local M = require("compat53.module") - - -- select the most powerful getmetatable function available - local gmt = type(debug) == "table" and debug.getmetatable or - getmetatable or function() return false end - -- metatable for file objects from Lua's standard io library - local file_meta = gmt(io.stdout) - - - -- detect LuaJIT (including LUAJIT_ENABLE_LUA52COMPAT compilation flag) - local is_luajit = (string.dump(function() end) or ""):sub(1, 3) == "\027LJ" - local is_luajit52 = is_luajit and - #setmetatable({}, { __len = function() return 1 end }) == 1 - - - if type(file_meta) == "table" and type(file_meta.__index) == "table" then - local file_mt = require("compat53.file_mt") - file_mt.update_file_meta(file_meta, is_luajit52) - end -- got a valid metatable for file objects - - - -- changes for Lua 5.1 only - if lua_version == "5.1" then - - -- cache globals - local error, pcall, rawset, setmetatable, tostring, xpcall = - error, pcall, rawset, setmetatable, tostring, xpcall - local coroutine, package, string = coroutine, package, string - local coroutine_resume = coroutine.resume - local coroutine_running = coroutine.running - local coroutine_status = coroutine.status - local coroutine_yield = coroutine.yield - local io_type = io.type - - - -- make package.searchers available as an alias for package.loaders - local p_index = { searchers = package.loaders } - setmetatable(package, { - __index = p_index, - __newindex = function(p, k, v) - if k == "searchers" then - rawset(p, "loaders", v) - p_index.searchers = v - else - rawset(p, k, v) - end - end - }) - - - if type(file_meta) == "table" and type(file_meta.__index) == "table" then - if not is_luajit then - local function helper(_, var_1, ...) - if var_1 == nil then - if (...) ~= nil then - error((...), 2) - end - end - return var_1, ... - end - - local function lines_iterator(st) - return helper(st, st.f:read(unpack(st, 1, st.n))) - end - - local file_write = file_meta.__index.write - file_meta.__index.write = function(self, ...) - local res, msg, errno = file_write(self, ...) - if res then - return self - else - return nil, msg, errno - end - end - - file_meta.__index.lines = function(self, ...) - if io_type(self) == "closed file" then - error("attempt to use a closed file", 2) - end - local st = { f=self, n=select('#', ...), ... } - for i = 1, st.n do - local t = type(st[i]) - if t == "string" then - local fmt = st[i]:match("^*?([aln])") - if not fmt then - error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) - end - st[i] = "*"..fmt - elseif t ~= "number" then - error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) - end - end - return lines_iterator, st - end - end -- not luajit - end -- file_meta valid - - - -- the (x)pcall implementations start a new coroutine internally - -- to allow yielding even in Lua 5.1. to allow for accurate - -- stack traces we keep track of the nested coroutine activations - -- in the weak tables below: - local weak_meta = { __mode = "kv" } - -- maps the internal pcall coroutines to the user coroutine that - -- *should* be running if pcall didn't use coroutines internally - local pcall_mainOf = setmetatable({}, weak_meta) - -- table that maps each running coroutine started by pcall to - -- the coroutine that resumed it (user coroutine *or* pcall - -- coroutine!) - local pcall_previous = setmetatable({}, weak_meta) - -- reverse of `pcall_mainOf`. maps a user coroutine to the - -- currently active pcall coroutine started within it - local pcall_callOf = setmetatable({}, weak_meta) - -- similar to `pcall_mainOf` but is used only while executing - -- the error handler of xpcall (thus no nesting is necessary!) - local xpcall_running = setmetatable({}, weak_meta) - - -- handle debug functions - if type(debug) == "table" then - local debug_getinfo = debug.getinfo - local debug_traceback = debug.traceback - - if not is_luajit then - local function calculate_trace_level(co, level) - if level ~= nil then - for out = 1, 1/0 do - local info = (co==nil) and debug_getinfo(out, "") or debug_getinfo(co, out, "") - if info == nil then - local max = out-1 - if level <= max then - return level - end - return nil, level-max - end - end - end - return 1 - end - - local stack_pattern = "\nstack traceback:" - local stack_replace = "" - function debug.traceback(co, msg, level) - local lvl - local nilmsg - if type(co) ~= "thread" then - co, msg, level = coroutine_running(), co, msg - end - if msg == nil then - msg = "" - nilmsg = true - elseif type(msg) ~= "string" then - return msg - end - if co == nil then - msg = debug_traceback(msg, level or 1) - else - local xpco = xpcall_running[co] - if xpco ~= nil then - lvl, level = calculate_trace_level(xpco, level) - if lvl then - msg = debug_traceback(xpco, msg, lvl) - else - msg = msg..stack_pattern - end - lvl, level = calculate_trace_level(co, level) - if lvl then - local trace = debug_traceback(co, "", lvl) - msg = msg..trace:gsub(stack_pattern, stack_replace) - end - else - co = pcall_callOf[co] or co - lvl, level = calculate_trace_level(co, level) - if lvl then - msg = debug_traceback(co, msg, lvl) - else - msg = msg..stack_pattern - end - end - co = pcall_previous[co] - while co ~= nil do - lvl, level = calculate_trace_level(co, level) - if lvl then - local trace = debug_traceback(co, "", lvl) - msg = msg..trace:gsub(stack_pattern, stack_replace) - end - co = pcall_previous[co] - end - end - if nilmsg then - msg = msg:gsub("^\n", "") - end - msg = msg:gsub("\n\t%(tail call%): %?", "\000") - msg = msg:gsub("\n\t%.%.%.\n", "\001\n") - msg = msg:gsub("\n\t%.%.%.$", "\001") - msg = msg:gsub("(%z+)\001(%z+)", function(some, other) - return "\n\t(..."..#some+#other.."+ tail call(s)...)" - end) - msg = msg:gsub("\001(%z+)", function(zeros) - return "\n\t(..."..#zeros.."+ tail call(s)...)" - end) - msg = msg:gsub("(%z+)\001", function(zeros) - return "\n\t(..."..#zeros.."+ tail call(s)...)" - end) - msg = msg:gsub("%z+", function(zeros) - return "\n\t(..."..#zeros.." tail call(s)...)" - end) - msg = msg:gsub("\001", function() - return "\n\t..." - end) - return msg - end - end -- is not luajit - end -- debug table available - - - if not is_luajit52 then - local coroutine_running52 = M.coroutine.running - function M.coroutine.running() - local co, ismain = coroutine_running52() - if ismain then - return co, true - else - return pcall_mainOf[co] or co, false - end - end - end - - if not is_luajit then - local function pcall_results(current, call, success, ...) - if coroutine_status(call) == "suspended" then - return pcall_results(current, call, coroutine_resume(call, coroutine_yield(...))) - end - if pcall_previous then - pcall_previous[call] = nil - local main = pcall_mainOf[call] - if main == current then current = nil end - pcall_callOf[main] = current - end - pcall_mainOf[call] = nil - return success, ... - end - - local function pcall_exec(current, call, ...) - local main = pcall_mainOf[current] or current - pcall_mainOf[call] = main - if pcall_previous then - pcall_previous[call] = current - pcall_callOf[main] = call - end - return pcall_results(current, call, coroutine_resume(call, ...)) - end - - local coroutine_create52 = M.coroutine.create - - local function pcall_coroutine(func) - if type(func) ~= "function" then - local callable = func - func = function (...) return callable(...) end - end - return coroutine_create52(func) - end - - function M.pcall(func, ...) - local current = coroutine_running() - if not current then return pcall(func, ...) end - return pcall_exec(current, pcall_coroutine(func), ...) - end - - local function xpcall_catch(current, call, msgh, success, ...) - if not success then - xpcall_running[current] = call - local ok, result = pcall(msgh, ...) - xpcall_running[current] = nil - if not ok then - return false, "error in error handling ("..tostring(result)..")" - end - return false, result - end - return true, ... - end - - function M.xpcall(f, msgh, ...) - local current = coroutine_running() - if not current then - local args, n = { ... }, select('#', ...) - return xpcall(function() return f(unpack(args, 1, n)) end, msgh) - end - local call = pcall_coroutine(f) - return xpcall_catch(current, call, msgh, pcall_exec(current, call, ...)) - end - end -- not luajit - - end -- lua 5.1 - - - -- handle exporting to global scope - local function extend_table(from, to) - if from ~= to then - for k,v in pairs(from) do - if type(v) == "table" and - type(to[k]) == "table" and - v ~= to[k] then - extend_table(v, to[k]) - else - to[k] = v - end - end - end - end - - extend_table(M, _G) - -end -- lua < 5.3 - --- vi: set expandtab softtabstop=3 shiftwidth=3 : diff --git a/lib/compat53/compat53/module.lua b/lib/compat53/compat53/module.lua deleted file mode 100644 index 52b1dd6..0000000 --- a/lib/compat53/compat53/module.lua +++ /dev/null @@ -1,894 +0,0 @@ -local _G, _VERSION = _G, _VERSION -local lua_version = _VERSION:sub(-3) - - -local M = _G - -if lua_version < "5.3" then - - -- cache globals in upvalues - local error, ipairs, pairs, pcall, require, select, setmetatable, type = - error, ipairs, pairs, pcall, require, select, setmetatable, type - local debug, io, math, package, string, table = - debug, io, math, package, string, table - local io_lines = io.lines - local io_read = io.read - local io_open = io.open - local io_popen = io.popen - local io_tmpfile = io.tmpfile - local unpack = lua_version == "5.1" and unpack or table.unpack - local debug_setmetatable = type(debug) == "table" and debug.setmetatable - - -- create module table - M = {} - local M_meta = { - __index = _G, - -- __newindex is set at the end - } - setmetatable(M, M_meta) - - -- create subtables - M.io = setmetatable({}, { __index = io }) - M.math = setmetatable({}, { __index = math }) - M.string = setmetatable({}, { __index = string }) - M.table = setmetatable({}, { __index = table }) - M.utf8 = {} - - - -- select the most powerful getmetatable function available - local gmt = type(debug) == "table" and debug.getmetatable or - getmetatable or function() return false end - - -- type checking functions - local checkinteger -- forward declararation - - local function argcheck(cond, i, f, extra) - if not cond then - error("bad argument #"..i.." to '"..f.."' ("..extra..")", 0) - end - end - - - -- load utf8 library - local utf8_ok, utf8lib = pcall(require, "compat53.utf8") - if utf8_ok then - if lua_version == "5.1" then - utf8lib.charpattern = "[%z\1-\127\194-\244][\128-\191]*" - end - for k,v in pairs(utf8lib) do - M.utf8[k] = v - end - package.loaded["utf8"] = M.utf8 - end - - - -- load table library - local table_ok, tablib = pcall(require, "compat53.table") - if table_ok then - for k,v in pairs(tablib) do - M.table[k] = v - end - end - - - -- load io functions - local io_ok, iolib = pcall(require, "compat53.io") - if io_ok then - for k,v in pairs(iolib) do - M.io[k] = v - end - end - - - -- load string packing functions - local str_ok, strlib = pcall(require, "compat53.string") - if str_ok then - for k,v in pairs(strlib) do - M.string[k] = v - end - end - - - -- try Roberto's struct module for string packing/unpacking if - -- compat53.string is unavailable - if not str_ok then - local struct_ok, struct = pcall(require, "struct") - if struct_ok then - M.string.pack = struct.pack - M.string.packsize = struct.size - M.string.unpack = struct.unpack - end - end - - - -- update math library - do - local maxint, minint = 1 - - while maxint+1 > maxint and 2*maxint > maxint do - maxint = maxint * 2 - end - if 2*maxint <= maxint then - maxint = 2*maxint-1 - minint = -maxint-1 - else - maxint = maxint - minint = -maxint - end - M.math.maxinteger = maxint - M.math.mininteger = minint - - function M.math.tointeger(n) - n = tonumber(n) - if type(n) == "number" and n <= maxint and n >= minint and n % 1 == 0 then - return n - end - return nil - end - - function M.math.type(n) - if type(n) == "number" then - if n <= maxint and n >= minint and n % 1 == 0 then - return "integer" - else - return "float" - end - else - return nil - end - end - - function checkinteger(x, i, f) - local t = type(x) - if t ~= "number" then - error("bad argument #"..i.." to '"..f.. - "' (number expected, got "..t..")", 0) - elseif x > maxint or x < minint or x % 1 ~= 0 then - error("bad argument #"..i.." to '"..f.. - "' (number has no integer representation)", 0) - else - return x - end - end - - function M.math.ult(m, n) - m = checkinteger(m, "1", "math.ult") - n = checkinteger(n, "2", "math.ult") - if m >= 0 and n < 0 then - return true - elseif m < 0 and n >= 0 then - return false - else - return m < n - end - end - end - - - -- assert should allow non-string error objects - function M.assert(cond, ...) - if cond then - return cond, ... - elseif select('#', ...) > 0 then - error((...), 0) - else - error("assertion failed!", 0) - end - end - - - -- ipairs should respect __index metamethod - do - local function ipairs_iterator(st, var) - var = var + 1 - local val = st[var] - if val ~= nil then - return var, st[var] - end - end - function M.ipairs(t) - if gmt(t) ~= nil then -- t has metatable - return ipairs_iterator, t, 0 - else - return ipairs(t) - end - end - end - - - -- make '*' optional for io.read and io.lines - do - local function addasterisk(fmt) - if type(fmt) == "string" and fmt:sub(1, 1) ~= "*" then - return "*"..fmt - else - return fmt - end - end - - function M.io.read(...) - local n = select('#', ...) - for i = 1, n do - local a = select(i, ...) - local b = addasterisk(a) - -- as an optimization we only allocate a table for the - -- modified format arguments when we have a '*' somewhere. - if a ~= b then - local args = { ... } - args[i] = b - for j = i+1, n do - args[j] = addasterisk(args[j]) - end - return io_read(unpack(args, 1, n)) - end - end - return io_read(...) - end - - -- PUC-Rio Lua 5.1 uses a different implementation for io.lines! - function M.io.lines(...) - local n = select('#', ...) - for i = 2, n do - local a = select(i, ...) - local b = addasterisk(a) - -- as an optimization we only allocate a table for the - -- modified format arguments when we have a '*' somewhere. - if a ~= b then - local args = { ... } - args[i] = b - for j = i+1, n do - args[j] = addasterisk(args[j]) - end - return io_lines(unpack(args, 1, n)) - end - end - return io_lines(...) - end - end - - - -- update table library (if C module not available) - if not table_ok then - local table_concat = table.concat - local table_insert = table.insert - local table_remove = table.remove - local table_sort = table.sort - - function M.table.concat(list, sep, i, j) - local mt = gmt(list) - if type(mt) == "table" and type(mt.__len) == "function" then - local src = list - list, i, j = {}, i or 1, j or mt.__len(src) - for k = i, j do - list[k] = src[k] - end - end - return table_concat(list, sep, i, j) - end - - function M.table.insert(list, ...) - local mt = gmt(list) - local has_mt = type(mt) == "table" - local has_len = has_mt and type(mt.__len) == "function" - if has_mt and (has_len or mt.__index or mt.__newindex) then - local e = (has_len and mt.__len(list) or #list)+1 - local nargs, pos, value = select('#', ...), ... - if nargs == 1 then - pos, value = e, pos - elseif nargs == 2 then - pos = checkinteger(pos, "2", "table.insert") - argcheck(1 <= pos and pos <= e, "2", "table.insert", - "position out of bounds" ) - else - error("wrong number of arguments to 'insert'", 0) - end - for i = e-1, pos, -1 do - list[i+1] = list[i] - end - list[pos] = value - else - return table_insert(list, ...) - end - end - - function M.table.move(a1, f, e, t, a2) - a2 = a2 or a1 - f = checkinteger(f, "2", "table.move") - argcheck(f > 0, "2", "table.move", - "initial position must be positive") - e = checkinteger(e, "3", "table.move") - t = checkinteger(t, "4", "table.move") - if e >= f then - local m, n, d = 0, e-f, 1 - if t > f then m, n, d = n, m, -1 end - for i = m, n, d do - a2[t+i] = a1[f+i] - end - end - return a2 - end - - function M.table.remove(list, pos) - local mt = gmt(list) - local has_mt = type(mt) == "table" - local has_len = has_mt and type(mt.__len) == "function" - if has_mt and (has_len or mt.__index or mt.__newindex) then - local e = (has_len and mt.__len(list) or #list) - pos = pos ~= nil and checkinteger(pos, "2", "table.remove") or e - if pos ~= e then - argcheck(1 <= pos and pos <= e+1, "2", "table.remove", - "position out of bounds" ) - end - local result = list[pos] - while pos < e do - list[pos] = list[pos+1] - pos = pos + 1 - end - list[pos] = nil - return result - else - return table_remove(list, pos) - end - end - - do - local function pivot(list, cmp, a, b) - local m = b - a - if m > 2 then - local c = a + (m-m%2)/2 - local x, y, z = list[a], list[b], list[c] - if not cmp(x, y) then - x, y, a, b = y, x, b, a - end - if not cmp(y, z) then - y, b = z, c - end - if not cmp(x, y) then - y, b = x, a - end - return b, y - else - return b, list[b] - end - end - - local function lt_cmp(a, b) - return a < b - end - - local function qsort(list, cmp, b, e) - if b < e then - local i, j, k, val = b, e, pivot(list, cmp, b, e) - while i < j do - while i < j and cmp(list[i], val) do - i = i + 1 - end - while i < j and not cmp(list[j], val) do - j = j - 1 - end - if i < j then - list[i], list[j] = list[j], list[i] - if i == k then k = j end -- update pivot position - i, j = i+1, j-1 - end - end - if i ~= k and not cmp(list[i], val) then - list[i], list[k] = val, list[i] - k = i -- update pivot position - end - qsort(list, cmp, b, i == k and i-1 or i) - return qsort(list, cmp, i+1, e) - end - end - - function M.table.sort(list, cmp) - local mt = gmt(list) - local has_mt = type(mt) == "table" - local has_len = has_mt and type(mt.__len) == "function" - if has_len then - cmp = cmp or lt_cmp - local len = mt.__len(list) - return qsort(list, cmp, 1, len) - else - return table_sort(list, cmp) - end - end - end - - local function unpack_helper(list, i, j, ...) - if j < i then - return ... - else - return unpack_helper(list, i, j-1, list[j], ...) - end - end - function M.table.unpack(list, i, j) - local mt = gmt(list) - local has_mt = type(mt) == "table" - local has_len = has_mt and type(mt.__len) == "function" - if has_mt and (has_len or mt.__index) then - i, j = i or 1, j or (has_len and mt.__len(list)) or #list - return unpack_helper(list, i, j) - else - return unpack(list, i, j) - end - end - end -- update table library - - - -- bring Lua 5.1 (and LuaJIT) up to speed with Lua 5.2 - if lua_version == "5.1" then - -- detect LuaJIT (including LUAJIT_ENABLE_LUA52COMPAT compilation flag) - local is_luajit = (string.dump(function() end) or ""):sub(1, 3) == "\027LJ" - local is_luajit52 = is_luajit and - #setmetatable({}, { __len = function() return 1 end }) == 1 - - -- cache globals in upvalues - local load, loadfile, loadstring, setfenv, xpcall = - load, loadfile, loadstring, setfenv, xpcall - local coroutine, os = coroutine, os - local coroutine_create = coroutine.create - local coroutine_resume = coroutine.resume - local coroutine_running = coroutine.running - local coroutine_status = coroutine.status - local coroutine_yield = coroutine.yield - local io_input = io.input - local io_open = io.open - local io_output = io.output - local io_write = io.write - local math_log = math.log - local os_execute = os.execute - local string_find = string.find - local string_format = string.format - local string_gmatch = string.gmatch - local string_gsub = string.gsub - local string_match = string.match - local string_rep = string.rep - local table_concat = table.concat - - -- create subtables - M.coroutine = setmetatable({}, { __index = coroutine }) - M.os = setmetatable({}, { __index = os }) - M.package = setmetatable({}, { __index = package }) - - -- handle debug functions - if type(debug) == "table" then - local debug_setfenv = debug.setfenv - local debug_getfenv = debug.getfenv - - M.debug = setmetatable({}, { __index = debug }) - - if not is_luajit52 then - function M.debug.setuservalue(obj, value) - if type(obj) ~= "userdata" then - error("bad argument #1 to 'setuservalue' (userdata expected, got ".. - type(obj)..")", 2) - end - if value == nil then value = _G end - if type(value) ~= "table" then - error("bad argument #2 to 'setuservalue' (table expected, got ".. - type(value)..")", 2) - end - return debug_setfenv(obj, value) - end - - function M.debug.getuservalue(obj) - if type(obj) ~= "userdata" then - return nil - else - local v = debug_getfenv(obj) - if v == _G or v == package then - return nil - end - return v - end - end - - function M.debug.setmetatable(value, tab) - debug_setmetatable(value, tab) - return value - end - end -- not luajit with compat52 enabled - end -- debug table available - - - if not is_luajit52 then - function M.pairs(t) - local mt = gmt(t) - if type(mt) == "table" and type(mt.__pairs) == "function" then - return mt.__pairs(t) - else - return pairs(t) - end - end - end - - - if not is_luajit then - local function check_mode(mode, prefix) - local has = { text = false, binary = false } - for i = 1,#mode do - local c = mode:sub(i, i) - if c == "t" then has.text = true end - if c == "b" then has.binary = true end - end - local t = prefix:sub(1, 1) == "\27" and "binary" or "text" - if not has[t] then - return "attempt to load a "..t.." chunk (mode is '"..mode.."')" - end - end - - function M.load(ld, source, mode, env) - mode = mode or "bt" - local chunk, msg - if type( ld ) == "string" then - if mode ~= "bt" then - local merr = check_mode(mode, ld) - if merr then return nil, merr end - end - chunk, msg = loadstring(ld, source) - else - local ld_type = type(ld) - if ld_type ~= "function" then - error("bad argument #1 to 'load' (function expected, got ".. - ld_type..")", 2) - end - if mode ~= "bt" then - local checked, merr = false, nil - local function checked_ld() - if checked then - return ld() - else - checked = true - local v = ld() - merr = check_mode(mode, v or "") - if merr then return nil end - return v - end - end - chunk, msg = load(checked_ld, source) - if merr then return nil, merr end - else - chunk, msg = load(ld, source) - end - end - if not chunk then - return chunk, msg - end - if env ~= nil then - setfenv(chunk, env) - end - return chunk - end - - M.loadstring = M.load - - function M.loadfile(file, mode, env) - mode = mode or "bt" - if mode ~= "bt" then - local f = io_open(file, "rb") - if f then - local prefix = f:read(1) - f:close() - if prefix then - local merr = check_mode(mode, prefix) - if merr then return nil, merr end - end - end - end - local chunk, msg = loadfile(file) - if not chunk then - return chunk, msg - end - if env ~= nil then - setfenv(chunk, env) - end - return chunk - end - end -- not luajit - - - if not is_luajit52 then - function M.rawlen(v) - local t = type(v) - if t ~= "string" and t ~= "table" then - error("bad argument #1 to 'rawlen' (table or string expected)", 2) - end - return #v - end - end - - - if not is_luajit then - function M.xpcall(f, msgh, ...) - local args, n = { ... }, select('#', ...) - return xpcall(function() return f(unpack(args, 1, n)) end, msgh) - end - end - - - if not is_luajit52 then - function M.os.execute(cmd) - local code = os_execute(cmd) - -- Lua 5.1 does not report exit by signal. - if code == 0 then - return true, "exit", code - else - if package.config:sub(1, 1) == '/' then - code = code/256 -- only correct on Linux! - end - return nil, "exit", code - end - end - end - - - if not table_ok and not is_luajit52 then - M.table.pack = function(...) - return { n = select('#', ...), ... } - end - end - - - local main_coroutine = coroutine_create(function() end) - - function M.coroutine.create(func) - local success, result = pcall(coroutine_create, func) - if not success then - if type(func) ~= "function" then - error("bad argument #1 (function expected)", 0) - end - result = coroutine_create(function(...) return func(...) end) - end - return result - end - - if not is_luajit52 then - function M.coroutine.running() - local co = coroutine_running() - if co then - return co, false - else - return main_coroutine, true - end - end - end - - function M.coroutine.yield(...) - local co, flag = coroutine_running() - if co and not flag then - return coroutine_yield(...) - else - error("attempt to yield from outside a coroutine", 0) - end - end - - if not is_luajit then - function M.coroutine.resume(co, ...) - if co == main_coroutine then - return false, "cannot resume non-suspended coroutine" - else - return coroutine_resume(co, ...) - end - end - - function M.coroutine.status(co) - local notmain = coroutine_running() - if co == main_coroutine then - return notmain and "normal" or "running" - else - return coroutine_status(co) - end - end - end -- not luajit - - - if not is_luajit then - M.math.log = function(x, base) - if base ~= nil then - return math_log(x)/math_log(base) - else - return math_log(x) - end - end - end - - - if not is_luajit then - function M.package.searchpath(name, path, sep, rep) - sep = (sep or "."):gsub("(%p)", "%%%1") - rep = (rep or package.config:sub(1, 1)):gsub("(%%)", "%%%1") - local pname = name:gsub(sep, rep):gsub("(%%)", "%%%1") - local msg = {} - for subpath in path:gmatch("[^;]+") do - local fpath = subpath:gsub("%?", pname) - local f = io_open(fpath, "r") - if f then - f:close() - return fpath - end - msg[#msg+1] = "\n\tno file '" .. fpath .. "'" - end - return nil, table_concat(msg) - end - end - - - local function fix_pattern(pattern) - return (string_gsub(pattern, "%z", "%%z")) - end - - function M.string.find(s, pattern, ...) - return string_find(s, fix_pattern(pattern), ...) - end - - function M.string.gmatch(s, pattern) - return string_gmatch(s, fix_pattern(pattern)) - end - - function M.string.gsub(s, pattern, ...) - return string_gsub(s, fix_pattern(pattern), ...) - end - - function M.string.match(s, pattern, ...) - return string_match(s, fix_pattern(pattern), ...) - end - - if not is_luajit then - function M.string.rep(s, n, sep) - if sep ~= nil and sep ~= "" and n >= 2 then - return s .. string_rep(sep..s, n-1) - else - return string_rep(s, n) - end - end - end - - if not is_luajit then - do - local addqt = { - ["\n"] = "\\\n", - ["\\"] = "\\\\", - ["\""] = "\\\"" - } - - local function addquoted(c, d) - return (addqt[c] or string_format(d~="" and "\\%03d" or "\\%d", c:byte()))..d - end - - function M.string.format(fmt, ...) - local args, n = { ... }, select('#', ...) - local i = 0 - local function adjust_fmt(lead, mods, kind) - if #lead % 2 == 0 then - i = i + 1 - if kind == "s" then - args[i] = _G.tostring(args[i]) - elseif kind == "q" then - args[i] = '"'..string_gsub(args[i], "([%z%c\\\"\n])(%d?)", addquoted)..'"' - return lead.."%"..mods.."s" - end - end - end - fmt = string_gsub(fmt, "(%%*)%%([%d%.%-%+%# ]*)(%a)", adjust_fmt) - return string_format(fmt, unpack(args, 1, n)) - end - end - end - - - function M.io.write(...) - local res, msg, errno = io_write(...) - if res then - return io_output() - else - return nil, msg, errno - end - end - - if not is_luajit then - local function helper(st, var_1, ...) - if var_1 == nil then - if st.doclose then st.f:close() end - if (...) ~= nil then - error((...), 2) - end - end - return var_1, ... - end - - local function lines_iterator(st) - return helper(st, st.f:read(unpack(st, 1, st.n))) - end - - function M.io.lines(fname, ...) - local doclose, file, msg - if fname ~= nil then - doclose, file, msg = true, io_open(fname, "r") - if not file then error(msg, 2) end - else - doclose, file = false, io_input() - end - local st = { f=file, doclose=doclose, n=select('#', ...), ... } - for i = 1, st.n do - local t = type(st[i]) - if t == "string" then - local fmt = st[i]:match("^%*?([aln])") - if not fmt then - error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) - end - st[i] = "*"..fmt - elseif t ~= "number" then - error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) - end - end - return lines_iterator, st - end - end -- not luajit - - if is_luajit then - local compat_file_meta = {} - local compat_file_meta_loaded = 0 - - local function load_compat_file_meta(file_meta) - -- fill compat_file_meta with original entries - for k, v in pairs(file_meta) do - compat_file_meta[k] = v - end - compat_file_meta.__index = {} - for k, v in pairs(file_meta.__index) do - compat_file_meta.__index[k] = v - end - - compat_file_meta_loaded = 1 - - -- update it with compatibility functions - local file_mt_ok, file_mt = pcall(require, "compat53.file_mt") - if file_mt_ok then - file_mt.update_file_meta(compat_file_meta, is_luajit52) - - compat_file_meta_loaded = 2 - end - end - - local function return_fd(fd, err, code) - if not fd then - return fd, err, code - end - if fd and debug_setmetatable then - if compat_file_meta_loaded == 0 then - local file_meta = gmt(fd) - load_compat_file_meta(file_meta) - end - if compat_file_meta_loaded == 2 then - debug_setmetatable(fd, compat_file_meta) - end - end - return fd - end - - function M.io.open(...) - return return_fd(io_open(...)) - end - - function M.io.popen(...) - return return_fd(io_popen(...)) - end - - function M.io.tmpfile(...) - return return_fd(io_tmpfile(...)) - end - end - - end -- lua 5.1 - - -- further write should be forwarded to _G - M_meta.__newindex = _G - -end -- lua < 5.3 - - --- return module table -return M - --- vi: set expandtab softtabstop=3 shiftwidth=3 : diff --git a/lib/compat53/lbitlib.c b/lib/compat53/lbitlib.c deleted file mode 100644 index db2652a..0000000 --- a/lib/compat53/lbitlib.c +++ /dev/null @@ -1,243 +0,0 @@ -/* -** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $ -** Standard library for bitwise operations -** See Copyright Notice in lua.h -*/ - -#define lbitlib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -#if defined(LUA_COMPAT_BITLIB) /* { */ - - -#define pushunsigned(L,n) (sizeof(lua_Integer) > 4 ? lua_pushinteger(L, (lua_Integer)(n)) : lua_pushnumber(L, (lua_Number)(n))) -static lua_Unsigned checkunsigned(lua_State *L, int i) { - if (sizeof(lua_Integer) > 4) - return (lua_Unsigned)luaL_checkinteger(L, i); - else { - lua_Number d = luaL_checknumber(L, i); - if (d < 0) - d = (d + 1) + (~(lua_Unsigned)0); - luaL_argcheck(L, d >= 0 && d <= (~(lua_Unsigned)0), i, "value out of range"); - return (lua_Unsigned)d; - } -} - - -/* number of bits to consider in a number */ -#if !defined(LUA_NBITS) -#define LUA_NBITS 32 -#endif - - -/* -** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must -** be made in two parts to avoid problems when LUA_NBITS is equal to the -** number of bits in a lua_Unsigned.) -*/ -#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) - - -/* macro to trim extra bits */ -#define trim(x) ((x) & ALLONES) - - -/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ -#define mask(n) (~((ALLONES << 1) << ((n) - 1))) - - - -static lua_Unsigned andaux (lua_State *L) { - int i, n = lua_gettop(L); - lua_Unsigned r = ~(lua_Unsigned)0; - for (i = 1; i <= n; i++) - r &= checkunsigned(L, i); - return trim(r); -} - - -static int b_and (lua_State *L) { - lua_Unsigned r = andaux(L); - pushunsigned(L, r); - return 1; -} - - -static int b_test (lua_State *L) { - lua_Unsigned r = andaux(L); - lua_pushboolean(L, r != 0); - return 1; -} - - -static int b_or (lua_State *L) { - int i, n = lua_gettop(L); - lua_Unsigned r = 0; - for (i = 1; i <= n; i++) - r |= checkunsigned(L, i); - pushunsigned(L, trim(r)); - return 1; -} - - -static int b_xor (lua_State *L) { - int i, n = lua_gettop(L); - lua_Unsigned r = 0; - for (i = 1; i <= n; i++) - r ^= checkunsigned(L, i); - pushunsigned(L, trim(r)); - return 1; -} - - -static int b_not (lua_State *L) { - lua_Unsigned r = ~checkunsigned(L, 1); - pushunsigned(L, trim(r)); - return 1; -} - - -static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) { - if (i < 0) { /* shift right? */ - i = -i; - r = trim(r); - if (i >= LUA_NBITS) r = 0; - else r >>= i; - } - else { /* shift left */ - if (i >= LUA_NBITS) r = 0; - else r <<= i; - r = trim(r); - } - pushunsigned(L, r); - return 1; -} - - -static int b_lshift (lua_State *L) { - return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2)); -} - - -static int b_rshift (lua_State *L) { - return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2)); -} - - -static int b_arshift (lua_State *L) { - lua_Unsigned r = checkunsigned(L, 1); - lua_Integer i = luaL_checkinteger(L, 2); - if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) - return b_shift(L, r, -i); - else { /* arithmetic shift for 'negative' number */ - if (i >= LUA_NBITS) r = ALLONES; - else - r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */ - pushunsigned(L, r); - return 1; - } -} - - -static int b_rot (lua_State *L, lua_Integer d) { - lua_Unsigned r = checkunsigned(L, 1); - int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ - r = trim(r); - if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ - r = (r << i) | (r >> (LUA_NBITS - i)); - pushunsigned(L, trim(r)); - return 1; -} - - -static int b_lrot (lua_State *L) { - return b_rot(L, luaL_checkinteger(L, 2)); -} - - -static int b_rrot (lua_State *L) { - return b_rot(L, -luaL_checkinteger(L, 2)); -} - - -/* -** get field and width arguments for field-manipulation functions, -** checking whether they are valid. -** ('luaL_error' called without 'return' to avoid later warnings about -** 'width' being used uninitialized.) -*/ -static int fieldargs (lua_State *L, int farg, int *width) { - lua_Integer f = luaL_checkinteger(L, farg); - lua_Integer w = luaL_optinteger(L, farg + 1, 1); - luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); - luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); - if (f + w > LUA_NBITS) - luaL_error(L, "trying to access non-existent bits"); - *width = (int)w; - return (int)f; -} - - -static int b_extract (lua_State *L) { - int w; - lua_Unsigned r = trim(checkunsigned(L, 1)); - int f = fieldargs(L, 2, &w); - r = (r >> f) & mask(w); - pushunsigned(L, r); - return 1; -} - - -static int b_replace (lua_State *L) { - int w; - lua_Unsigned r = trim(checkunsigned(L, 1)); - lua_Unsigned v = trim(checkunsigned(L, 2)); - int f = fieldargs(L, 3, &w); - lua_Unsigned m = mask(w); - r = (r & ~(m << f)) | ((v & m) << f); - pushunsigned(L, r); - return 1; -} - - -static const luaL_Reg bitlib[] = { - {"arshift", b_arshift}, - {"band", b_and}, - {"bnot", b_not}, - {"bor", b_or}, - {"bxor", b_xor}, - {"btest", b_test}, - {"extract", b_extract}, - {"lrotate", b_lrot}, - {"lshift", b_lshift}, - {"replace", b_replace}, - {"rrotate", b_rrot}, - {"rshift", b_rshift}, - {NULL, NULL} -}; - - - -LUAMOD_API int luaopen_bit32 (lua_State *L) { - luaL_newlib(L, bitlib); - return 1; -} - - -#else /* }{ */ - - -LUAMOD_API int luaopen_bit32 (lua_State *L) { - return luaL_error(L, "library 'bit32' has been deprecated"); -} - -#endif /* } */ diff --git a/lib/compat53/liolib.c b/lib/compat53/liolib.c deleted file mode 100644 index 8a9e75c..0000000 --- a/lib/compat53/liolib.c +++ /dev/null @@ -1,776 +0,0 @@ -/* -** $Id: liolib.c,v 2.151.1.1 2017/04/19 17:29:57 roberto Exp $ -** Standard I/O (and system) library -** See Copyright Notice in lua.h -*/ - -#define liolib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include <ctype.h> -#include <errno.h> -#include <locale.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - - - -/* -** Change this macro to accept other modes for 'fopen' besides -** the standard ones. -*/ -#if !defined(l_checkmode) - -/* accepted extensions to 'mode' in 'fopen' */ -#if !defined(L_MODEEXT) -#define L_MODEEXT "b" -#endif - -/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */ -static int l_checkmode (const char *mode) { - return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && - (*mode != '+' || (++mode, 1)) && /* skip if char is '+' */ - (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */ -} - -#endif - -/* -** {====================================================== -** l_popen spawns a new process connected to the current -** one through the file streams. -** ======================================================= -*/ - -#if !defined(l_popen) /* { */ - -#if defined(LUA_USE_POSIX) /* { */ - -#define l_popen(L,c,m) (fflush(NULL), popen(c,m)) -#define l_pclose(L,file) (pclose(file)) - -#elif defined(LUA_USE_WINDOWS) /* }{ */ - -#define l_popen(L,c,m) (_popen(c,m)) -#define l_pclose(L,file) (_pclose(file)) - -#else /* }{ */ - -/* ISO C definitions */ -#define l_popen(L,c,m) \ - ((void)((void)c, m), \ - luaL_error(L, "'popen' not supported"), \ - (FILE*)0) -#define l_pclose(L,file) ((void)L, (void)file, -1) - -#endif /* } */ - -#endif /* } */ - -/* }====================================================== */ - - -#if !defined(l_getc) /* { */ - -#if defined(LUA_USE_POSIX) -#define l_getc(f) getc_unlocked(f) -#define l_lockfile(f) flockfile(f) -#define l_unlockfile(f) funlockfile(f) -#else -#define l_getc(f) getc(f) -#define l_lockfile(f) ((void)0) -#define l_unlockfile(f) ((void)0) -#endif - -#endif /* } */ - - -/* -** {====================================================== -** l_fseek: configuration for longer offsets -** ======================================================= -*/ - -#if !defined(l_fseek) /* { */ - -#if defined(LUA_USE_POSIX) /* { */ - -#include <sys/types.h> - -#define l_fseek(f,o,w) fseeko(f,o,w) -#define l_ftell(f) ftello(f) -#define l_seeknum off_t - -#elif defined(LUA_USE_WINDOWS) && !defined(_CRTIMP_TYPEINFO) \ - && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ - -/* Windows (but not DDK) and Visual C++ 2005 or higher */ -#define l_fseek(f,o,w) _fseeki64(f,o,w) -#define l_ftell(f) _ftelli64(f) -#define l_seeknum __int64 - -#else /* }{ */ - -/* ISO C definitions */ -#define l_fseek(f,o,w) fseek(f,o,w) -#define l_ftell(f) ftell(f) -#define l_seeknum long - -#endif /* } */ - -#endif /* } */ - -/* }====================================================== */ - - -#define IO_PREFIX "_IO_" -#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1) -#define IO_INPUT (IO_PREFIX "input") -#define IO_OUTPUT (IO_PREFIX "output") - - -typedef luaL_Stream LStream; - - -#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) - -#define isclosed(p) ((p)->closef == NULL) - - -static int io_type (lua_State *L) { - LStream *p; - luaL_checkany(L, 1); - p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); - if (p == NULL) - lua_pushnil(L); /* not a file */ - else if (isclosed(p)) - lua_pushliteral(L, "closed file"); - else - lua_pushliteral(L, "file"); - return 1; -} - - -static int f_tostring (lua_State *L) { - LStream *p = tolstream(L); - if (isclosed(p)) - lua_pushliteral(L, "file (closed)"); - else - lua_pushfstring(L, "file (%p)", p->f); - return 1; -} - - -static FILE *tofile (lua_State *L) { - LStream *p = tolstream(L); - if (isclosed(p)) - luaL_error(L, "attempt to use a closed file"); - lua_assert(p->f); - return p->f; -} - - -/* -** When creating file handles, always creates a 'closed' file handle -** before opening the actual file; so, if there is a memory error, the -** handle is in a consistent state. -*/ -static LStream *newprefile (lua_State *L) { - LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); - p->closef = NULL; /* mark file handle as 'closed' */ - luaL_setmetatable(L, LUA_FILEHANDLE); - return p; -} - - -/* -** Calls the 'close' function from a file handle. The 'volatile' avoids -** a bug in some versions of the Clang compiler (e.g., clang 3.0 for -** 32 bits). -*/ -static int aux_close (lua_State *L) { - LStream *p = tolstream(L); - volatile lua_CFunction cf = p->closef; - p->closef = NULL; /* mark stream as closed */ - return (*cf)(L); /* close it */ -} - - -static int f_close (lua_State *L) { - tofile(L); /* make sure argument is an open stream */ - return aux_close(L); -} - - -static int io_close (lua_State *L) { - if (lua_isnone(L, 1)) /* no argument? */ - lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ - return f_close(L); -} - - -static int f_gc (lua_State *L) { - LStream *p = tolstream(L); - if (!isclosed(p) && p->f != NULL) - aux_close(L); /* ignore closed and incompletely open files */ - return 0; -} - - -/* -** function to close regular files -*/ -static int io_fclose (lua_State *L) { - LStream *p = tolstream(L); - int res = fclose(p->f); - return luaL_fileresult(L, (res == 0), NULL); -} - - -static LStream *newfile (lua_State *L) { - LStream *p = newprefile(L); - p->f = NULL; - p->closef = &io_fclose; - return p; -} - - -static void opencheck (lua_State *L, const char *fname, const char *mode) { - LStream *p = newfile(L); - p->f = fopen(fname, mode); - if (p->f == NULL) - luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno)); -} - - -static int io_open (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - LStream *p = newfile(L); - const char *md = mode; /* to traverse/check mode */ - luaL_argcheck(L, l_checkmode(md), 2, "invalid mode"); - p->f = fopen(filename, mode); - return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; -} - - -/* -** function to close 'popen' files -*/ -static int io_pclose (lua_State *L) { - LStream *p = tolstream(L); - return luaL_execresult(L, l_pclose(L, p->f)); -} - - -static int io_popen (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - LStream *p = newprefile(L); - p->f = l_popen(L, filename, mode); - p->closef = &io_pclose; - return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; -} - - -static int io_tmpfile (lua_State *L) { - LStream *p = newfile(L); - p->f = tmpfile(); - return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; -} - - -static FILE *getiofile (lua_State *L, const char *findex) { - LStream *p; - lua_getfield(L, LUA_REGISTRYINDEX, findex); - p = (LStream *)lua_touserdata(L, -1); - if (isclosed(p)) - luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN); - return p->f; -} - - -static int g_iofile (lua_State *L, const char *f, const char *mode) { - if (!lua_isnoneornil(L, 1)) { - const char *filename = lua_tostring(L, 1); - if (filename) - opencheck(L, filename, mode); - else { - tofile(L); /* check that it's a valid file handle */ - lua_pushvalue(L, 1); - } - lua_setfield(L, LUA_REGISTRYINDEX, f); - } - /* return current value */ - lua_getfield(L, LUA_REGISTRYINDEX, f); - return 1; -} - - -static int io_input (lua_State *L) { - return g_iofile(L, IO_INPUT, "r"); -} - - -static int io_output (lua_State *L) { - return g_iofile(L, IO_OUTPUT, "w"); -} - - -static int io_readline (lua_State *L); - - -/* -** maximum number of arguments to 'f:lines'/'io.lines' (it + 3 must fit -** in the limit for upvalues of a closure) -*/ -#define MAXARGLINE 250 - -static void aux_lines (lua_State *L, int toclose) { - int n = lua_gettop(L) - 1; /* number of arguments to read */ - luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments"); - lua_pushinteger(L, n); /* number of arguments to read */ - lua_pushboolean(L, toclose); /* close/not close file when finished */ - lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */ - lua_pushcclosure(L, io_readline, 3 + n); -} - - -static int f_lines (lua_State *L) { - tofile(L); /* check that it's a valid file handle */ - aux_lines(L, 0); - return 1; -} - - -static int io_lines (lua_State *L) { - int toclose; - if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ - if (lua_isnil(L, 1)) { /* no file name? */ - lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */ - lua_replace(L, 1); /* put it at index 1 */ - tofile(L); /* check that it's a valid file handle */ - toclose = 0; /* do not close it after iteration */ - } - else { /* open a new file */ - const char *filename = luaL_checkstring(L, 1); - opencheck(L, filename, "r"); - lua_replace(L, 1); /* put file at index 1 */ - toclose = 1; /* close it after iteration */ - } - aux_lines(L, toclose); - return 1; -} - - -/* -** {====================================================== -** READ -** ======================================================= -*/ - - -/* maximum length of a numeral */ -#if !defined (L_MAXLENNUM) -#define L_MAXLENNUM 200 -#endif - - -/* auxiliary structure used by 'read_number' */ -typedef struct { - FILE *f; /* file being read */ - int c; /* current character (look ahead) */ - int n; /* number of elements in buffer 'buff' */ - char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */ -} RN; - - -/* -** Add current char to buffer (if not out of space) and read next one -*/ -static int nextc (RN *rn) { - if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */ - rn->buff[0] = '\0'; /* invalidate result */ - return 0; /* fail */ - } - else { - rn->buff[rn->n++] = rn->c; /* save current char */ - rn->c = l_getc(rn->f); /* read next one */ - return 1; - } -} - - -/* -** Accept current char if it is in 'set' (of size 2) -*/ -static int test2 (RN *rn, const char *set) { - if (rn->c == set[0] || rn->c == set[1]) - return nextc(rn); - else return 0; -} - - -/* -** Read a sequence of (hex)digits -*/ -static int readdigits (RN *rn, int hex) { - int count = 0; - while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn)) - count++; - return count; -} - - -/* -** Read a number: first reads a valid prefix of a numeral into a buffer. -** Then it calls 'lua_stringtonumber' to check whether the format is -** correct and to convert it to a Lua number -*/ -static int read_number (lua_State *L, FILE *f) { - RN rn; - int count = 0; - int hex = 0; - char decp[2]; - rn.f = f; rn.n = 0; - decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */ - decp[1] = '.'; /* always accept a dot */ - l_lockfile(rn.f); - do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ - test2(&rn, "-+"); /* optional signal */ - if (test2(&rn, "00")) { - if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ - else count = 1; /* count initial '0' as a valid digit */ - } - count += readdigits(&rn, hex); /* integral part */ - if (test2(&rn, decp)) /* decimal point? */ - count += readdigits(&rn, hex); /* fractional part */ - if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */ - test2(&rn, "-+"); /* exponent signal */ - readdigits(&rn, 0); /* exponent digits */ - } - ungetc(rn.c, rn.f); /* unread look-ahead char */ - l_unlockfile(rn.f); - rn.buff[rn.n] = '\0'; /* finish string */ - if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */ - return 1; /* ok */ - else { /* invalid format */ - lua_pushnil(L); /* "result" to be removed */ - return 0; /* read fails */ - } -} - - -static int test_eof (lua_State *L, FILE *f) { - int c = getc(f); - ungetc(c, f); /* no-op when c == EOF */ - lua_pushliteral(L, ""); - return (c != EOF); -} - - -static int read_line (lua_State *L, FILE *f, int chop) { - luaL_Buffer b; - int c = '\0'; - luaL_buffinit(L, &b); - while (c != EOF && c != '\n') { /* repeat until end of line */ - char *buff = luaL_prepbuffer(&b); /* preallocate buffer */ - int i = 0; - l_lockfile(f); /* no memory errors can happen inside the lock */ - while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') - buff[i++] = c; - l_unlockfile(f); - luaL_addsize(&b, i); - } - if (!chop && c == '\n') /* want a newline and have one? */ - luaL_addchar(&b, c); /* add ending newline to result */ - luaL_pushresult(&b); /* close buffer */ - /* return ok if read something (either a newline or something else) */ - return (c == '\n' || lua_rawlen(L, -1) > 0); -} - - -static void read_all (lua_State *L, FILE *f) { - size_t nr; - luaL_Buffer b; - luaL_buffinit(L, &b); - do { /* read file in chunks of LUAL_BUFFERSIZE bytes */ - char *p = luaL_prepbuffer(&b); - nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f); - luaL_addsize(&b, nr); - } while (nr == LUAL_BUFFERSIZE); - luaL_pushresult(&b); /* close buffer */ -} - - -static int read_chars (lua_State *L, FILE *f, size_t n) { - size_t nr; /* number of chars actually read */ - char *p; - luaL_Buffer b; - luaL_buffinit(L, &b); - p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */ - nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */ - luaL_addsize(&b, nr); - luaL_pushresult(&b); /* close buffer */ - return (nr > 0); /* true iff read something */ -} - - -static int g_read (lua_State *L, FILE *f, int first) { - int nargs = lua_gettop(L) - 1; - int success; - int n; - clearerr(f); - if (nargs == 0) { /* no arguments? */ - success = read_line(L, f, 1); - n = first+1; /* to return 1 result */ - } - else { /* ensure stack space for all results and for auxlib's buffer */ - luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); - success = 1; - for (n = first; nargs-- && success; n++) { - if (lua_type(L, n) == LUA_TNUMBER) { - size_t l = (size_t)luaL_checkinteger(L, n); - success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); - } - else { - const char *p = luaL_checkstring(L, n); - if (*p == '*') p++; /* skip optional '*' (for compatibility) */ - switch (*p) { - case 'n': /* number */ - success = read_number(L, f); - break; - case 'l': /* line */ - success = read_line(L, f, 1); - break; - case 'L': /* line with end-of-line */ - success = read_line(L, f, 0); - break; - case 'a': /* file */ - read_all(L, f); /* read entire file */ - success = 1; /* always success */ - break; - default: - return luaL_argerror(L, n, "invalid format"); - } - } - } - } - if (ferror(f)) - return luaL_fileresult(L, 0, NULL); - if (!success) { - lua_pop(L, 1); /* remove last result */ - lua_pushnil(L); /* push nil instead */ - } - return n - first; -} - - -static int io_read (lua_State *L) { - return g_read(L, getiofile(L, IO_INPUT), 1); -} - - -static int f_read (lua_State *L) { - return g_read(L, tofile(L), 2); -} - - -static int io_readline (lua_State *L) { - LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); - int i; - int n = (int)lua_tointeger(L, lua_upvalueindex(2)); - if (isclosed(p)) /* file is already closed? */ - return luaL_error(L, "file is already closed"); - lua_settop(L , 1); - luaL_checkstack(L, n, "too many arguments"); - for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ - lua_pushvalue(L, lua_upvalueindex(3 + i)); - n = g_read(L, p->f, 2); /* 'n' is number of results */ - lua_assert(n > 0); /* should return at least a nil */ - if (lua_toboolean(L, -n)) /* read at least one value? */ - return n; /* return them */ - else { /* first result is nil: EOF or error */ - if (n > 1) { /* is there error information? */ - /* 2nd result is error message */ - return luaL_error(L, "%s", lua_tostring(L, -n + 1)); - } - if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ - lua_settop(L, 0); - lua_pushvalue(L, lua_upvalueindex(1)); - aux_close(L); /* close it */ - } - return 0; - } -} - -/* }====================================================== */ - - -static int g_write (lua_State *L, FILE *f, int arg) { - int nargs = lua_gettop(L) - arg; - int status = 1; - for (; nargs--; arg++) { - if (lua_type(L, arg) == LUA_TNUMBER) { - /* optimization: could be done exactly as for strings */ - int len = lua_isinteger(L, arg) - ? fprintf(f, LUA_INTEGER_FMT, - (LUAI_UACINT)lua_tointeger(L, arg)) - : fprintf(f, LUA_NUMBER_FMT, - (LUAI_UACNUMBER)lua_tonumber(L, arg)); - status = status && (len > 0); - } - else { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - status = status && (fwrite(s, sizeof(char), l, f) == l); - } - } - if (status) return 1; /* file handle already on stack top */ - else return luaL_fileresult(L, status, NULL); -} - - -static int io_write (lua_State *L) { - return g_write(L, getiofile(L, IO_OUTPUT), 1); -} - - -static int f_write (lua_State *L) { - FILE *f = tofile(L); - lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ - return g_write(L, f, 2); -} - - -static int f_seek (lua_State *L) { - static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; - static const char *const modenames[] = {"set", "cur", "end", NULL}; - FILE *f = tofile(L); - int op = luaL_checkoption(L, 2, "cur", modenames); - lua_Integer p3 = luaL_optinteger(L, 3, 0); - l_seeknum offset = (l_seeknum)p3; - luaL_argcheck(L, (lua_Integer)offset == p3, 3, - "not an integer in proper range"); - op = l_fseek(f, offset, mode[op]); - if (op) - return luaL_fileresult(L, 0, NULL); /* error */ - else { - lua_pushinteger(L, (lua_Integer)l_ftell(f)); - return 1; - } -} - - -static int f_setvbuf (lua_State *L) { - static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; - static const char *const modenames[] = {"no", "full", "line", NULL}; - FILE *f = tofile(L); - int op = luaL_checkoption(L, 2, NULL, modenames); - lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); - int res = setvbuf(f, NULL, mode[op], (size_t)sz); - return luaL_fileresult(L, res == 0, NULL); -} - - - -static int io_flush (lua_State *L) { - return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); -} - - -static int f_flush (lua_State *L) { - return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); -} - - -/* -** functions for 'io' library -*/ -static const luaL_Reg iolib[] = { - {"close", io_close}, - {"flush", io_flush}, - {"input", io_input}, - {"lines", io_lines}, - {"open", io_open}, - {"output", io_output}, - {"popen", io_popen}, - {"read", io_read}, - {"tmpfile", io_tmpfile}, - {"type", io_type}, - {"write", io_write}, - {NULL, NULL} -}; - - -/* -** methods for file handles -*/ -static const luaL_Reg flib[] = { - {"close", f_close}, - {"flush", f_flush}, - {"lines", f_lines}, - {"read", f_read}, - {"seek", f_seek}, - {"setvbuf", f_setvbuf}, - {"write", f_write}, - {"__gc", f_gc}, - {"__tostring", f_tostring}, - {NULL, NULL} -}; - - -static void createmeta (lua_State *L) { - luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ - lua_pushvalue(L, -1); /* push metatable */ - lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ - luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ - lua_pop(L, 1); /* pop new metatable */ -} - - -/* -** function to (not) close the standard files stdin, stdout, and stderr -*/ -static int io_noclose (lua_State *L) { - LStream *p = tolstream(L); - p->closef = &io_noclose; /* keep file opened */ - lua_pushnil(L); - lua_pushliteral(L, "cannot close standard file"); - return 2; -} - - -static void createstdfile (lua_State *L, FILE *f, const char *k, - const char *fname) { - LStream *p = newprefile(L); - p->f = f; - p->closef = &io_noclose; - if (k != NULL) { - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */ - } - lua_setfield(L, -2, fname); /* add file to module */ -} - - -LUAMOD_API int luaopen_io (lua_State *L) { - luaL_newlib(L, iolib); /* new module */ - createmeta(L); - /* create (and set) default files */ - createstdfile(L, stdin, IO_INPUT, "stdin"); - createstdfile(L, stdout, IO_OUTPUT, "stdout"); - createstdfile(L, stderr, NULL, "stderr"); - return 1; -} - diff --git a/lib/compat53/lprefix.h b/lib/compat53/lprefix.h deleted file mode 100644 index 0f83906..0000000 --- a/lib/compat53/lprefix.h +++ /dev/null @@ -1,282 +0,0 @@ -/* -** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ -** Definitions for Lua code that must come before any other header file -** See Copyright Notice in lua.h -*/ - -#ifndef lprefix_h -#define lprefix_h - - -/* -** Allows POSIX/XSI stuff -*/ -#if !defined(LUA_USE_C89) /* { */ - -#if !defined(_XOPEN_SOURCE) -#define _XOPEN_SOURCE 600 -#elif _XOPEN_SOURCE == 0 -#undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ -#endif - -/* -** Allows manipulation of large files in gcc and some other compilers -*/ -#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) -#define _LARGEFILE_SOURCE 1 -#define _FILE_OFFSET_BITS 64 -#endif - -#endif /* } */ - - -/* -** Windows stuff -*/ -#if defined(_WIN32) /* { */ - -#if !defined(_CRT_SECURE_NO_WARNINGS) -#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ -#endif - -#endif /* } */ - - -/* COMPAT53 adaptation */ -#include "c-api/compat-5.3.h" - -#undef LUAMOD_API -#define LUAMOD_API extern - - -#ifdef lutf8lib_c -# define luaopen_utf8 luaopen_compat53_utf8 -/* we don't support the %U format string of lua_pushfstring! - * code below adapted from the Lua 5.3 sources: - */ -static const char *compat53_utf8_escape (lua_State* L, long x) { - if (x < 0x80) { /* ASCII */ - char c = (char)x; - lua_pushlstring(L, &c, 1); - } else { - char buff[8] = { 0 }; - unsigned int mfb = 0x3f; - int n = 1; - do { - buff[8 - (n++)] = (char)(0x80|(x & 0x3f)); - x >>= 6; - mfb >>= 1; - } while (x > mfb); - buff[8-n] = (char)((~mfb << 1) | x); - lua_pushlstring(L, buff+8-n, n); - } - return lua_tostring(L, -1); -} -# define lua_pushfstring(L, fmt, l) \ - compat53_utf8_escape(L, l) -#endif - - -#ifdef ltablib_c -# define luaopen_table luaopen_compat53_table -# ifndef LUA_MAXINTEGER -/* conservative estimate: */ -# define LUA_MAXINTEGER INT_MAX -# endif -#endif /* ltablib_c */ - - -#ifdef lstrlib_c -#include <locale.h> -#include <lualib.h> -/* move the string library open function out of the way (we only take - * the string packing functions)! - */ -# define luaopen_string luaopen_string_XXX -/* used in string.format implementation, which we don't use: */ -# ifndef LUA_INTEGER_FRMLEN -# define LUA_INTEGER_FRMLEN "" -# define LUA_NUMBER_FRMLEN "" -# endif -# ifndef LUA_MININTEGER -# define LUA_MININTEGER 0 -# endif -# ifndef LUA_INTEGER_FMT -# define LUA_INTEGER_FMT "%d" -# endif -# ifndef LUAI_UACINT -# define LUAI_UACINT lua_Integer -# endif -/* different Lua 5.3 versions have conflicting variants of this macro - * in luaconf.h, there's a fallback implementation in lstrlib.c, and - * the macro isn't used for string (un)packing anyway! - * */ -# undef lua_number2strx -# if LUA_VERSION_NUM < 503 -/* lstrlib assumes that lua_Integer and lua_Unsigned have the same - * size, so we use the unsigned equivalent of ptrdiff_t! */ -# define lua_Unsigned size_t -# endif -# ifndef l_mathlim -# ifdef LUA_NUMBER_DOUBLE -# define l_mathlim(n) (DBL_##n) -# else -# define l_mathlim(n) (FLT_##n) -# endif -# endif -# ifndef l_mathop -# ifdef LUA_NUMBER_DOUBLE -# define l_mathop(op) op -# else -# define l_mathop(op) op##f -# endif -# endif -# ifndef lua_getlocaledecpoint -# define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) -# endif -# ifndef l_sprintf -# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -# 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 -# endif - -static int str_pack (lua_State *L); -static int str_packsize (lua_State *L); -static int str_unpack (lua_State *L); -LUAMOD_API int luaopen_compat53_string (lua_State *L) { - luaL_Reg const funcs[] = { - { "pack", str_pack }, - { "packsize", str_packsize }, - { "unpack", str_unpack }, - { NULL, NULL } - }; - luaL_newlib(L, funcs); - return 1; -} -/* fake CLANG feature detection on other compilers */ -# ifndef __has_attribute -# define __has_attribute(x) 0 -# endif -/* make luaopen_string(_XXX) static, so it (and all other referenced - * string functions) won't be included in the resulting dll - * (hopefully). - */ -# undef LUAMOD_API -# if defined(__GNUC__) || __has_attribute(__unused__) -# define LUAMOD_API __attribute__((__unused__)) static -# else -# define LUAMOD_API static -# endif -#endif /* lstrlib.c */ - -#endif - - -#ifdef liolib_c -/* move the io library open function out of the way (we only take - * the popen and type functions)! - */ -# define luaopen_io luaopen_io_XXX - -#include <locale.h> -#include <lualib.h> - -# if !defined(lua_getlocaledecpoint) -# define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) -# endif - -# ifndef LUA_INTEGER_FMT -# define LUA_INTEGER_FMT "%ld" -# endif -# ifndef LUAI_UACINT -# define LUAI_UACINT lua_Integer -# endif - -/* choose which popen implementation to pick */ -# if (defined(_WIN32) && !defined(__CYGWIN__)) -# define LUA_USE_WINDOWS 1 -# endif -# if (!defined(LUA_USE_WINDOWS) && !defined(LUA_USE_POSIX)) && \ - ((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \ - (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) || \ - defined(__APPLE__)) -# define LUA_USE_POSIX 1 -# endif - -typedef struct COMPAT53_luaL_Stream { - FILE *f; /* stream (NULL for incompletely created streams) */ - lua_CFunction closef; /* to close stream (NULL for closed streams) */ -} COMPAT53_luaL_Stream; - -#define luaL_Stream COMPAT53_luaL_Stream - -#define COMPAT53_LUA_PFILEHANDLE "PFILE*" - -static int io_ptype (lua_State *L) { - luaL_Stream *p; - luaL_checkany(L, 1); - p = (luaL_Stream *)luaL_testudata(L, 1, COMPAT53_LUA_PFILEHANDLE); - if (p) { - /* Lua 5.3 implementation, for popen files */ - if (p->closef == NULL) - lua_pushliteral(L, "closed file"); - else - lua_pushliteral(L, "file"); - return 1; - } else { - /* Lua 5.1 implementation, for plain files */ - void *ud = lua_touserdata(L, 1); - lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); - if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) - lua_pushnil(L); /* not a file */ - else if (*((FILE **)ud) == NULL) - lua_pushliteral(L, "closed file"); - else - lua_pushliteral(L, "file"); - return 1; - } -} - -static int io_popen (lua_State *L); -static void createmeta (lua_State *L); - -# undef LUA_FILEHANDLE -# define LUA_FILEHANDLE COMPAT53_LUA_PFILEHANDLE - -LUAMOD_API int luaopen_compat53_io (lua_State *L) { - luaL_Reg const funcs[] = { - -/* for PUC-Rio Lua 5.1 only */ -# if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 && !defined(LUA_JITLIBNAME) - - { "popen", io_popen }, - { "type", io_ptype }, - -# endif /* for PUC-Rio Lua 5.1 only */ - - { NULL, NULL } - }; - luaL_newlib(L, funcs); - createmeta(L); - return 1; -} - - -/* fake CLANG feature detection on other compilers */ -# ifndef __has_attribute -# define __has_attribute(x) 0 -# endif -/* make luaopen_io(_XXX) static, so it (and all other referenced - * io functions) won't be included in the resulting dll - * (hopefully). - */ -# undef LUAMOD_API -# if defined(__GNUC__) || __has_attribute(__unused__) -# define LUAMOD_API __attribute__((__unused__)) static -# else -# define LUAMOD_API static -# endif - -#endif /* iolib.c */ diff --git a/lib/compat53/lstrlib.c b/lib/compat53/lstrlib.c deleted file mode 100644 index b4bed7e..0000000 --- a/lib/compat53/lstrlib.c +++ /dev/null @@ -1,1584 +0,0 @@ -/* -** $Id: lstrlib.c,v 1.254.1.1 2017/04/19 17:29:57 roberto Exp $ -** Standard library for string operations and pattern-matching -** See Copyright Notice in lua.h -*/ - -#define lstrlib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include <ctype.h> -#include <float.h> -#include <limits.h> -#include <locale.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -/* -** maximum number of captures that a pattern can do during -** pattern-matching. This limit is arbitrary, but must fit in -** an unsigned char. -*/ -#if !defined(LUA_MAXCAPTURES) -#define LUA_MAXCAPTURES 32 -#endif - - -/* macro to 'unsign' a character */ -#define uchar(c) ((unsigned char)(c)) - - -/* -** Some sizes are better limited to fit in 'int', but must also fit in -** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) -*/ -#define MAX_SIZET ((size_t)(~(size_t)0)) - -#define MAXSIZE \ - (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX)) - - - - -static int str_len (lua_State *L) { - size_t l; - luaL_checklstring(L, 1, &l); - lua_pushinteger(L, (lua_Integer)l); - return 1; -} - - -/* translate a relative string position: negative means back from end */ -static lua_Integer posrelat (lua_Integer pos, size_t len) { - if (pos >= 0) return pos; - else if (0u - (size_t)pos > len) return 0; - else return (lua_Integer)len + pos + 1; -} - - -static int str_sub (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - lua_Integer start = posrelat(luaL_checkinteger(L, 2), l); - lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l); - if (start < 1) start = 1; - if (end > (lua_Integer)l) end = l; - if (start <= end) - lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1); - else lua_pushliteral(L, ""); - return 1; -} - - -static int str_reverse (lua_State *L) { - size_t l, i; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - char *p = luaL_buffinitsize(L, &b, l); - for (i = 0; i < l; i++) - p[i] = s[l - i - 1]; - luaL_pushresultsize(&b, l); - return 1; -} - - -static int str_lower (lua_State *L) { - size_t l; - size_t i; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - char *p = luaL_buffinitsize(L, &b, l); - for (i=0; i<l; i++) - p[i] = tolower(uchar(s[i])); - luaL_pushresultsize(&b, l); - return 1; -} - - -static int str_upper (lua_State *L) { - size_t l; - size_t i; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - char *p = luaL_buffinitsize(L, &b, l); - for (i=0; i<l; i++) - p[i] = toupper(uchar(s[i])); - luaL_pushresultsize(&b, l); - return 1; -} - - -static int str_rep (lua_State *L) { - size_t l, lsep; - const char *s = luaL_checklstring(L, 1, &l); - lua_Integer n = luaL_checkinteger(L, 2); - const char *sep = luaL_optlstring(L, 3, "", &lsep); - if (n <= 0) lua_pushliteral(L, ""); - else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */ - return luaL_error(L, "resulting string too large"); - else { - size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; - luaL_Buffer b; - char *p = luaL_buffinitsize(L, &b, totallen); - while (n-- > 1) { /* first n-1 copies (followed by separator) */ - memcpy(p, s, l * sizeof(char)); p += l; - if (lsep > 0) { /* empty 'memcpy' is not that cheap */ - memcpy(p, sep, lsep * sizeof(char)); - p += lsep; - } - } - memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ - luaL_pushresultsize(&b, totallen); - } - return 1; -} - - -static int str_byte (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l); - lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l); - int n, i; - if (posi < 1) posi = 1; - if (pose > (lua_Integer)l) pose = l; - if (posi > pose) return 0; /* empty interval; return no values */ - if (pose - posi >= INT_MAX) /* arithmetic overflow? */ - return luaL_error(L, "string slice too long"); - n = (int)(pose - posi) + 1; - luaL_checkstack(L, n, "string slice too long"); - for (i=0; i<n; i++) - lua_pushinteger(L, uchar(s[posi+i-1])); - return n; -} - - -static int str_char (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int i; - luaL_Buffer b; - char *p = luaL_buffinitsize(L, &b, n); - for (i=1; i<=n; i++) { - lua_Integer c = luaL_checkinteger(L, i); - luaL_argcheck(L, uchar(c) == c, i, "value out of range"); - p[i - 1] = uchar(c); - } - luaL_pushresultsize(&b, n); - return 1; -} - - -static int writer (lua_State *L, const void *b, size_t size, void *B) { - (void)L; - luaL_addlstring((luaL_Buffer *) B, (const char *)b, size); - return 0; -} - - -static int str_dump (lua_State *L) { - luaL_Buffer b; - int strip = lua_toboolean(L, 2); - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_settop(L, 1); - luaL_buffinit(L,&b); - if (lua_dump(L, writer, &b, strip) != 0) - return luaL_error(L, "unable to dump given function"); - luaL_pushresult(&b); - return 1; -} - - - -/* -** {====================================================== -** PATTERN MATCHING -** ======================================================= -*/ - - -#define CAP_UNFINISHED (-1) -#define CAP_POSITION (-2) - - -typedef struct MatchState { - const char *src_init; /* init of source string */ - const char *src_end; /* end ('\0') of source string */ - const char *p_end; /* end ('\0') of pattern */ - lua_State *L; - int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ - unsigned char level; /* total number of captures (finished or unfinished) */ - struct { - const char *init; - ptrdiff_t len; - } capture[LUA_MAXCAPTURES]; -} MatchState; - - -/* recursive function */ -static const char *match (MatchState *ms, const char *s, const char *p); - - -/* maximum recursion depth for 'match' */ -#if !defined(MAXCCALLS) -#define MAXCCALLS 200 -#endif - - -#define L_ESC '%' -#define SPECIALS "^$*+?.([%-" - - -static int check_capture (MatchState *ms, int l) { - l -= '1'; - if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) - return luaL_error(ms->L, "invalid capture index %%%d", l + 1); - return l; -} - - -static int capture_to_close (MatchState *ms) { - int level = ms->level; - for (level--; level>=0; level--) - if (ms->capture[level].len == CAP_UNFINISHED) return level; - return luaL_error(ms->L, "invalid pattern capture"); -} - - -static const char *classend (MatchState *ms, const char *p) { - switch (*p++) { - case L_ESC: { - if (p == ms->p_end) - luaL_error(ms->L, "malformed pattern (ends with '%%')"); - return p+1; - } - case '[': { - if (*p == '^') p++; - do { /* look for a ']' */ - if (p == ms->p_end) - luaL_error(ms->L, "malformed pattern (missing ']')"); - if (*(p++) == L_ESC && p < ms->p_end) - p++; /* skip escapes (e.g. '%]') */ - } while (*p != ']'); - return p+1; - } - default: { - return p; - } - } -} - - -static int match_class (int c, int cl) { - int res; - switch (tolower(cl)) { - case 'a' : res = isalpha(c); break; - case 'c' : res = iscntrl(c); break; - case 'd' : res = isdigit(c); break; - case 'g' : res = isgraph(c); break; - case 'l' : res = islower(c); break; - case 'p' : res = ispunct(c); break; - case 's' : res = isspace(c); break; - case 'u' : res = isupper(c); break; - case 'w' : res = isalnum(c); break; - case 'x' : res = isxdigit(c); break; - case 'z' : res = (c == 0); break; /* deprecated option */ - default: return (cl == c); - } - return (islower(cl) ? res : !res); -} - - -static int matchbracketclass (int c, const char *p, const char *ec) { - int sig = 1; - if (*(p+1) == '^') { - sig = 0; - p++; /* skip the '^' */ - } - while (++p < ec) { - if (*p == L_ESC) { - p++; - if (match_class(c, uchar(*p))) - return sig; - } - else if ((*(p+1) == '-') && (p+2 < ec)) { - p+=2; - if (uchar(*(p-2)) <= c && c <= uchar(*p)) - return sig; - } - else if (uchar(*p) == c) return sig; - } - return !sig; -} - - -static int singlematch (MatchState *ms, const char *s, const char *p, - const char *ep) { - if (s >= ms->src_end) - return 0; - else { - int c = uchar(*s); - switch (*p) { - case '.': return 1; /* matches any char */ - case L_ESC: return match_class(c, uchar(*(p+1))); - case '[': return matchbracketclass(c, p, ep-1); - default: return (uchar(*p) == c); - } - } -} - - -static const char *matchbalance (MatchState *ms, const char *s, - const char *p) { - if (p >= ms->p_end - 1) - luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); - if (*s != *p) return NULL; - else { - int b = *p; - int e = *(p+1); - int cont = 1; - while (++s < ms->src_end) { - if (*s == e) { - if (--cont == 0) return s+1; - } - else if (*s == b) cont++; - } - } - return NULL; /* string ends out of balance */ -} - - -static const char *max_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - ptrdiff_t i = 0; /* counts maximum expand for item */ - while (singlematch(ms, s + i, p, ep)) - i++; - /* keeps trying to match with the maximum repetitions */ - while (i>=0) { - const char *res = match(ms, (s+i), ep+1); - if (res) return res; - i--; /* else didn't match; reduce 1 repetition to try again */ - } - return NULL; -} - - -static const char *min_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - for (;;) { - const char *res = match(ms, s, ep+1); - if (res != NULL) - return res; - else if (singlematch(ms, s, p, ep)) - s++; /* try with one more repetition */ - else return NULL; - } -} - - -static const char *start_capture (MatchState *ms, const char *s, - const char *p, int what) { - const char *res; - int level = ms->level; - if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); - ms->capture[level].init = s; - ms->capture[level].len = what; - ms->level = level+1; - if ((res=match(ms, s, p)) == NULL) /* match failed? */ - ms->level--; /* undo capture */ - return res; -} - - -static const char *end_capture (MatchState *ms, const char *s, - const char *p) { - int l = capture_to_close(ms); - const char *res; - ms->capture[l].len = s - ms->capture[l].init; /* close capture */ - if ((res = match(ms, s, p)) == NULL) /* match failed? */ - ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ - return res; -} - - -static const char *match_capture (MatchState *ms, const char *s, int l) { - size_t len; - l = check_capture(ms, l); - len = ms->capture[l].len; - if ((size_t)(ms->src_end-s) >= len && - memcmp(ms->capture[l].init, s, len) == 0) - return s+len; - else return NULL; -} - - -static const char *match (MatchState *ms, const char *s, const char *p) { - if (ms->matchdepth-- == 0) - luaL_error(ms->L, "pattern too complex"); - init: /* using goto's to optimize tail recursion */ - if (p != ms->p_end) { /* end of pattern? */ - switch (*p) { - case '(': { /* start capture */ - if (*(p + 1) == ')') /* position capture? */ - s = start_capture(ms, s, p + 2, CAP_POSITION); - else - s = start_capture(ms, s, p + 1, CAP_UNFINISHED); - break; - } - case ')': { /* end capture */ - s = end_capture(ms, s, p + 1); - break; - } - case '$': { - if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */ - goto dflt; /* no; go to default */ - s = (s == ms->src_end) ? s : NULL; /* check end of string */ - break; - } - case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ - switch (*(p + 1)) { - case 'b': { /* balanced string? */ - s = matchbalance(ms, s, p + 2); - if (s != NULL) { - p += 4; goto init; /* return match(ms, s, p + 4); */ - } /* else fail (s == NULL) */ - break; - } - case 'f': { /* frontier? */ - const char *ep; char previous; - p += 2; - if (*p != '[') - luaL_error(ms->L, "missing '[' after '%%f' in pattern"); - ep = classend(ms, p); /* points to what is next */ - previous = (s == ms->src_init) ? '\0' : *(s - 1); - if (!matchbracketclass(uchar(previous), p, ep - 1) && - matchbracketclass(uchar(*s), p, ep - 1)) { - p = ep; goto init; /* return match(ms, s, ep); */ - } - s = NULL; /* match failed */ - break; - } - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - case '8': case '9': { /* capture results (%0-%9)? */ - s = match_capture(ms, s, uchar(*(p + 1))); - if (s != NULL) { - p += 2; goto init; /* return match(ms, s, p + 2) */ - } - break; - } - default: goto dflt; - } - break; - } - default: dflt: { /* pattern class plus optional suffix */ - const char *ep = classend(ms, p); /* points to optional suffix */ - /* does not match at least once? */ - if (!singlematch(ms, s, p, ep)) { - if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ - p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ - } - else /* '+' or no suffix */ - s = NULL; /* fail */ - } - else { /* matched once */ - switch (*ep) { /* handle optional suffix */ - case '?': { /* optional */ - const char *res; - if ((res = match(ms, s + 1, ep + 1)) != NULL) - s = res; - else { - p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ - } - break; - } - case '+': /* 1 or more repetitions */ - s++; /* 1 match already done */ - /* FALLTHROUGH */ - case '*': /* 0 or more repetitions */ - s = max_expand(ms, s, p, ep); - break; - case '-': /* 0 or more repetitions (minimum) */ - s = min_expand(ms, s, p, ep); - break; - default: /* no suffix */ - s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ - } - } - break; - } - } - } - ms->matchdepth++; - return s; -} - - - -static const char *lmemfind (const char *s1, size_t l1, - const char *s2, size_t l2) { - if (l2 == 0) return s1; /* empty strings are everywhere */ - else if (l2 > l1) return NULL; /* avoids a negative 'l1' */ - else { - const char *init; /* to search for a '*s2' inside 's1' */ - l2--; /* 1st char will be checked by 'memchr' */ - l1 = l1-l2; /* 's2' cannot be found after that */ - while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { - init++; /* 1st char is already checked */ - if (memcmp(init, s2+1, l2) == 0) - return init-1; - else { /* correct 'l1' and 's1' to try again */ - l1 -= init-s1; - s1 = init; - } - } - return NULL; /* not found */ - } -} - - -static void push_onecapture (MatchState *ms, int i, const char *s, - const char *e) { - if (i >= ms->level) { - if (i == 0) /* ms->level == 0, too */ - lua_pushlstring(ms->L, s, e - s); /* add whole match */ - else - luaL_error(ms->L, "invalid capture index %%%d", i + 1); - } - else { - ptrdiff_t l = ms->capture[i].len; - if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); - if (l == CAP_POSITION) - lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); - else - lua_pushlstring(ms->L, ms->capture[i].init, l); - } -} - - -static int push_captures (MatchState *ms, const char *s, const char *e) { - int i; - int nlevels = (ms->level == 0 && s) ? 1 : ms->level; - luaL_checkstack(ms->L, nlevels, "too many captures"); - for (i = 0; i < nlevels; i++) - push_onecapture(ms, i, s, e); - return nlevels; /* number of strings pushed */ -} - - -/* check whether pattern has no special characters */ -static int nospecials (const char *p, size_t l) { - size_t upto = 0; - do { - if (strpbrk(p + upto, SPECIALS)) - return 0; /* pattern has a special character */ - upto += strlen(p + upto) + 1; /* may have more after \0 */ - } while (upto <= l); - return 1; /* no special chars found */ -} - - -static void prepstate (MatchState *ms, lua_State *L, - const char *s, size_t ls, const char *p, size_t lp) { - ms->L = L; - ms->matchdepth = MAXCCALLS; - ms->src_init = s; - ms->src_end = s + ls; - ms->p_end = p + lp; -} - - -static void reprepstate (MatchState *ms) { - ms->level = 0; - lua_assert(ms->matchdepth == MAXCCALLS); -} - - -static int str_find_aux (lua_State *L, int find) { - size_t ls, lp; - const char *s = luaL_checklstring(L, 1, &ls); - const char *p = luaL_checklstring(L, 2, &lp); - lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls); - if (init < 1) init = 1; - else if (init > (lua_Integer)ls + 1) { /* start after string's end? */ - lua_pushnil(L); /* cannot find anything */ - return 1; - } - /* explicit request or no special characters? */ - if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { - /* do a plain search */ - const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp); - if (s2) { - lua_pushinteger(L, (s2 - s) + 1); - lua_pushinteger(L, (s2 - s) + lp); - return 2; - } - } - else { - MatchState ms; - const char *s1 = s + init - 1; - int anchor = (*p == '^'); - if (anchor) { - p++; lp--; /* skip anchor character */ - } - prepstate(&ms, L, s, ls, p, lp); - do { - const char *res; - reprepstate(&ms); - if ((res=match(&ms, s1, p)) != NULL) { - if (find) { - lua_pushinteger(L, (s1 - s) + 1); /* start */ - lua_pushinteger(L, res - s); /* end */ - return push_captures(&ms, NULL, 0) + 2; - } - else - return push_captures(&ms, s1, res); - } - } while (s1++ < ms.src_end && !anchor); - } - lua_pushnil(L); /* not found */ - return 1; -} - - -static int str_find (lua_State *L) { - return str_find_aux(L, 1); -} - - -static int str_match (lua_State *L) { - return str_find_aux(L, 0); -} - - -/* state for 'gmatch' */ -typedef struct GMatchState { - const char *src; /* current position */ - const char *p; /* pattern */ - const char *lastmatch; /* end of last match */ - MatchState ms; /* match state */ -} GMatchState; - - -static int gmatch_aux (lua_State *L) { - GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); - const char *src; - gm->ms.L = L; - for (src = gm->src; src <= gm->ms.src_end; src++) { - const char *e; - reprepstate(&gm->ms); - if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) { - gm->src = gm->lastmatch = e; - return push_captures(&gm->ms, src, e); - } - } - return 0; /* not found */ -} - - -static int gmatch (lua_State *L) { - size_t ls, lp; - const char *s = luaL_checklstring(L, 1, &ls); - const char *p = luaL_checklstring(L, 2, &lp); - GMatchState *gm; - lua_settop(L, 2); /* keep them on closure to avoid being collected */ - gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState)); - prepstate(&gm->ms, L, s, ls, p, lp); - gm->src = s; gm->p = p; gm->lastmatch = NULL; - lua_pushcclosure(L, gmatch_aux, 3); - return 1; -} - - -static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e) { - size_t l, i; - lua_State *L = ms->L; - const char *news = lua_tolstring(L, 3, &l); - for (i = 0; i < l; i++) { - if (news[i] != L_ESC) - luaL_addchar(b, news[i]); - else { - i++; /* skip ESC */ - if (!isdigit(uchar(news[i]))) { - if (news[i] != L_ESC) - luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); - luaL_addchar(b, news[i]); - } - else if (news[i] == '0') - luaL_addlstring(b, s, e - s); - else { - push_onecapture(ms, news[i] - '1', s, e); - luaL_tolstring(L, -1, NULL); /* if number, convert it to string */ - lua_remove(L, -2); /* remove original value */ - luaL_addvalue(b); /* add capture to accumulated result */ - } - } - } -} - - -static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e, int tr) { - lua_State *L = ms->L; - switch (tr) { - case LUA_TFUNCTION: { - int n; - lua_pushvalue(L, 3); - n = push_captures(ms, s, e); - lua_call(L, n, 1); - break; - } - case LUA_TTABLE: { - push_onecapture(ms, 0, s, e); - lua_gettable(L, 3); - break; - } - default: { /* LUA_TNUMBER or LUA_TSTRING */ - add_s(ms, b, s, e); - return; - } - } - if (!lua_toboolean(L, -1)) { /* nil or false? */ - lua_pop(L, 1); - lua_pushlstring(L, s, e - s); /* keep original text */ - } - else if (!lua_isstring(L, -1)) - luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); - luaL_addvalue(b); /* add result to accumulator */ -} - - -static int str_gsub (lua_State *L) { - size_t srcl, lp; - const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ - const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ - const char *lastmatch = NULL; /* end of last match */ - int tr = lua_type(L, 3); /* replacement type */ - lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ - int anchor = (*p == '^'); - lua_Integer n = 0; /* replacement count */ - MatchState ms; - luaL_Buffer b; - luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || - tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, - "string/function/table expected"); - luaL_buffinit(L, &b); - if (anchor) { - p++; lp--; /* skip anchor character */ - } - prepstate(&ms, L, src, srcl, p, lp); - while (n < max_s) { - const char *e; - reprepstate(&ms); /* (re)prepare state for new match */ - if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ - n++; - add_value(&ms, &b, src, e, tr); /* add replacement to buffer */ - src = lastmatch = e; - } - else if (src < ms.src_end) /* otherwise, skip one character */ - luaL_addchar(&b, *src++); - else break; /* end of subject */ - if (anchor) break; - } - luaL_addlstring(&b, src, ms.src_end-src); - luaL_pushresult(&b); - lua_pushinteger(L, n); /* number of substitutions */ - return 2; -} - -/* }====================================================== */ - - - -/* -** {====================================================== -** STRING FORMAT -** ======================================================= -*/ - -#if !defined(lua_number2strx) /* { */ - -/* -** Hexadecimal floating-point formatter -*/ - -#include <math.h> - -#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char)) - - -/* -** Number of bits that goes into the first digit. It can be any value -** between 1 and 4; the following definition tries to align the number -** to nibble boundaries by making what is left after that first digit a -** multiple of 4. -*/ -#define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1) - - -/* -** Add integer part of 'x' to buffer and return new 'x' -*/ -static lua_Number adddigit (char *buff, int n, lua_Number x) { - lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */ - int d = (int)dd; - buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */ - return x - dd; /* return what is left */ -} - - -static int num2straux (char *buff, int sz, lua_Number x) { - /* if 'inf' or 'NaN', format it like '%g' */ - if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL) - return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x); - else if (x == 0) { /* can be -0... */ - /* create "0" or "-0" followed by exponent */ - return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x); - } - else { - int e; - lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */ - int n = 0; /* character count */ - if (m < 0) { /* is number negative? */ - buff[n++] = '-'; /* add signal */ - m = -m; /* make it positive */ - } - buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */ - m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */ - e -= L_NBFD; /* this digit goes before the radix point */ - if (m > 0) { /* more digits? */ - buff[n++] = lua_getlocaledecpoint(); /* add radix point */ - do { /* add as many digits as needed */ - m = adddigit(buff, n++, m * 16); - } while (m > 0); - } - n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */ - lua_assert(n < sz); - return n; - } -} - - -static int lua_number2strx (lua_State *L, char *buff, int sz, - const char *fmt, lua_Number x) { - int n = num2straux(buff, sz, x); - if (fmt[SIZELENMOD] == 'A') { - int i; - for (i = 0; i < n; i++) - buff[i] = toupper(uchar(buff[i])); - } - else if (fmt[SIZELENMOD] != 'a') - return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); - return n; -} - -#endif /* } */ - - -/* -** Maximum size of each formatted item. This maximum size is produced -** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', -** and '\0') + number of decimal digits to represent maxfloat (which -** is maximum exponent + 1). (99+3+1 then rounded to 120 for "extra -** expenses", such as locale-dependent stuff) -*/ -#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP)) - - -/* valid flags in a format specification */ -#define FLAGS "-+ #0" - -/* -** maximum size of each format specification (such as "%-099.99d") -*/ -#define MAX_FORMAT 32 - - -static void addquoted (luaL_Buffer *b, const char *s, size_t len) { - luaL_addchar(b, '"'); - while (len--) { - if (*s == '"' || *s == '\\' || *s == '\n') { - luaL_addchar(b, '\\'); - luaL_addchar(b, *s); - } - else if (iscntrl(uchar(*s))) { - char buff[10]; - if (!isdigit(uchar(*(s+1)))) - l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s)); - else - l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s)); - luaL_addstring(b, buff); - } - else - luaL_addchar(b, *s); - s++; - } - luaL_addchar(b, '"'); -} - - -/* -** Ensures the 'buff' string uses a dot as the radix character. -*/ -static void checkdp (char *buff, int nb) { - if (memchr(buff, '.', nb) == NULL) { /* no dot? */ - char point = lua_getlocaledecpoint(); /* try locale point */ - char *ppoint = (char *)memchr(buff, point, nb); - if (ppoint) *ppoint = '.'; /* change it to a dot */ - } -} - - -static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { - switch (lua_type(L, arg)) { - case LUA_TSTRING: { - size_t len; - const char *s = lua_tolstring(L, arg, &len); - addquoted(b, s, len); - break; - } - case LUA_TNUMBER: { - char *buff = luaL_prepbuffsize(b, MAX_ITEM); - int nb; - if (!lua_isinteger(L, arg)) { /* float? */ - lua_Number n = lua_tonumber(L, arg); /* write as hexa ('%a') */ - nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n); - checkdp(buff, nb); /* ensure it uses a dot */ - } - else { /* integers */ - lua_Integer n = lua_tointeger(L, arg); - const char *format = (n == LUA_MININTEGER) /* corner case? */ - ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */ - : LUA_INTEGER_FMT; /* else use default format */ - nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n); - } - luaL_addsize(b, nb); - break; - } - case LUA_TNIL: case LUA_TBOOLEAN: { - luaL_tolstring(L, arg, NULL); - luaL_addvalue(b); - break; - } - default: { - luaL_argerror(L, arg, "value has no literal form"); - } - } -} - - -static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { - const char *p = strfrmt; - while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ - if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) - luaL_error(L, "invalid format (repeated flags)"); - if (isdigit(uchar(*p))) p++; /* skip width */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - if (*p == '.') { - p++; - if (isdigit(uchar(*p))) p++; /* skip precision */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - } - if (isdigit(uchar(*p))) - luaL_error(L, "invalid format (width or precision too long)"); - *(form++) = '%'; - memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char)); - form += (p - strfrmt) + 1; - *form = '\0'; - return p; -} - - -/* -** add length modifier into formats -*/ -static void addlenmod (char *form, const char *lenmod) { - size_t l = strlen(form); - size_t lm = strlen(lenmod); - char spec = form[l - 1]; - strcpy(form + l - 1, lenmod); - form[l + lm - 1] = spec; - form[l + lm] = '\0'; -} - - -static int str_format (lua_State *L) { - int top = lua_gettop(L); - int arg = 1; - size_t sfl; - const char *strfrmt = luaL_checklstring(L, arg, &sfl); - const char *strfrmt_end = strfrmt+sfl; - luaL_Buffer b; - luaL_buffinit(L, &b); - while (strfrmt < strfrmt_end) { - if (*strfrmt != L_ESC) - luaL_addchar(&b, *strfrmt++); - else if (*++strfrmt == L_ESC) - luaL_addchar(&b, *strfrmt++); /* %% */ - else { /* format item */ - char form[MAX_FORMAT]; /* to store the format ('%...') */ - char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ - int nb = 0; /* number of bytes in added item */ - if (++arg > top) - luaL_argerror(L, arg, "no value"); - strfrmt = scanformat(L, strfrmt, form); - switch (*strfrmt++) { - case 'c': { - nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg)); - break; - } - case 'd': case 'i': - case 'o': case 'u': case 'x': case 'X': { - lua_Integer n = luaL_checkinteger(L, arg); - addlenmod(form, LUA_INTEGER_FRMLEN); - nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n); - break; - } - case 'a': case 'A': - addlenmod(form, LUA_NUMBER_FRMLEN); - nb = lua_number2strx(L, buff, MAX_ITEM, form, - luaL_checknumber(L, arg)); - break; - case 'e': case 'E': case 'f': - case 'g': case 'G': { - lua_Number n = luaL_checknumber(L, arg); - addlenmod(form, LUA_NUMBER_FRMLEN); - nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n); - break; - } - case 'q': { - addliteral(L, &b, arg); - break; - } - case 's': { - size_t l; - const char *s = luaL_tolstring(L, arg, &l); - if (form[2] == '\0') /* no modifiers? */ - luaL_addvalue(&b); /* keep entire string */ - else { - luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); - if (!strchr(form, '.') && l >= 100) { - /* no precision and string is too long to be formatted */ - luaL_addvalue(&b); /* keep entire string */ - } - else { /* format the string into 'buff' */ - nb = l_sprintf(buff, MAX_ITEM, form, s); - lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ - } - } - break; - } - default: { /* also treat cases 'pnLlh' */ - return luaL_error(L, "invalid option '%%%c' to 'format'", - *(strfrmt - 1)); - } - } - lua_assert(nb < MAX_ITEM); - luaL_addsize(&b, nb); - } - } - luaL_pushresult(&b); - return 1; -} - -/* }====================================================== */ - - -/* -** {====================================================== -** PACK/UNPACK -** ======================================================= -*/ - - -/* value used for padding */ -#if !defined(LUAL_PACKPADBYTE) -#define LUAL_PACKPADBYTE 0x00 -#endif - -/* maximum size for the binary representation of an integer */ -#define MAXINTSIZE 16 - -/* number of bits in a character */ -#define NB CHAR_BIT - -/* mask for one character (NB 1's) */ -#define MC ((1 << NB) - 1) - -/* size of a lua_Integer */ -#define SZINT ((int)sizeof(lua_Integer)) - - -/* dummy union to get native endianness */ -static const union { - int dummy; - char little; /* true iff machine is little endian */ -} nativeendian = {1}; - - -/* dummy structure to get native alignment requirements */ -struct cD { - char c; - union { double d; void *p; lua_Integer i; lua_Number n; } u; -}; - -#define MAXALIGN (offsetof(struct cD, u)) - - -/* -** Union for serializing floats -*/ -typedef union Ftypes { - float f; - double d; - lua_Number n; - char buff[5 * sizeof(lua_Number)]; /* enough for any float type */ -} Ftypes; - - -/* -** information to pack/unpack stuff -*/ -typedef struct Header { - lua_State *L; - int islittle; - int maxalign; -} Header; - - -/* -** options for pack/unpack -*/ -typedef enum KOption { - Kint, /* signed integers */ - Kuint, /* unsigned integers */ - Kfloat, /* floating-point numbers */ - Kchar, /* fixed-length strings */ - Kstring, /* strings with prefixed length */ - Kzstr, /* zero-terminated strings */ - Kpadding, /* padding */ - Kpaddalign, /* padding for alignment */ - Knop /* no-op (configuration or spaces) */ -} KOption; - - -/* -** Read an integer numeral from string 'fmt' or return 'df' if -** there is no numeral -*/ -static int digit (int c) { return '0' <= c && c <= '9'; } - -static int getnum (const char **fmt, int df) { - if (!digit(**fmt)) /* no number? */ - return df; /* return default value */ - else { - int a = 0; - do { - a = a*10 + (*((*fmt)++) - '0'); - } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10); - return a; - } -} - - -/* -** Read an integer numeral and raises an error if it is larger -** than the maximum size for integers. -*/ -static int getnumlimit (Header *h, const char **fmt, int df) { - int sz = getnum(fmt, df); - if (sz > MAXINTSIZE || sz <= 0) - return luaL_error(h->L, "integral size (%d) out of limits [1,%d]", - sz, MAXINTSIZE); - return sz; -} - - -/* -** Initialize Header -*/ -static void initheader (lua_State *L, Header *h) { - h->L = L; - h->islittle = nativeendian.little; - h->maxalign = 1; -} - - -/* -** Read and classify next option. 'size' is filled with option's size. -*/ -static KOption getoption (Header *h, const char **fmt, int *size) { - int opt = *((*fmt)++); - *size = 0; /* default */ - switch (opt) { - case 'b': *size = sizeof(char); return Kint; - case 'B': *size = sizeof(char); return Kuint; - case 'h': *size = sizeof(short); return Kint; - case 'H': *size = sizeof(short); return Kuint; - case 'l': *size = sizeof(long); return Kint; - case 'L': *size = sizeof(long); return Kuint; - case 'j': *size = sizeof(lua_Integer); return Kint; - case 'J': *size = sizeof(lua_Integer); return Kuint; - case 'T': *size = sizeof(size_t); return Kuint; - case 'f': *size = sizeof(float); return Kfloat; - case 'd': *size = sizeof(double); return Kfloat; - case 'n': *size = sizeof(lua_Number); return Kfloat; - case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; - case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; - case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; - case 'c': - *size = getnum(fmt, -1); - if (*size == -1) - luaL_error(h->L, "missing size for format option 'c'"); - return Kchar; - case 'z': return Kzstr; - case 'x': *size = 1; return Kpadding; - case 'X': return Kpaddalign; - case ' ': break; - case '<': h->islittle = 1; break; - case '>': h->islittle = 0; break; - case '=': h->islittle = nativeendian.little; break; - case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break; - default: luaL_error(h->L, "invalid format option '%c'", opt); - } - return Knop; -} - - -/* -** Read, classify, and fill other details about the next option. -** 'psize' is filled with option's size, 'notoalign' with its -** alignment requirements. -** Local variable 'size' gets the size to be aligned. (Kpadal option -** always gets its full alignment, other options are limited by -** the maximum alignment ('maxalign'). Kchar option needs no alignment -** despite its size. -*/ -static KOption getdetails (Header *h, size_t totalsize, - const char **fmt, int *psize, int *ntoalign) { - KOption opt = getoption(h, fmt, psize); - int align = *psize; /* usually, alignment follows size */ - if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ - if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) - luaL_argerror(h->L, 1, "invalid next option for option 'X'"); - } - if (align <= 1 || opt == Kchar) /* need no alignment? */ - *ntoalign = 0; - else { - if (align > h->maxalign) /* enforce maximum alignment */ - align = h->maxalign; - if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ - luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); - *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); - } - return opt; -} - - -/* -** Pack integer 'n' with 'size' bytes and 'islittle' endianness. -** The final 'if' handles the case when 'size' is larger than -** the size of a Lua integer, correcting the extra sign-extension -** bytes if necessary (by default they would be zeros). -*/ -static void packint (luaL_Buffer *b, lua_Unsigned n, - int islittle, int size, int neg) { - char *buff = luaL_prepbuffsize(b, size); - int i; - buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ - for (i = 1; i < size; i++) { - n >>= NB; - buff[islittle ? i : size - 1 - i] = (char)(n & MC); - } - if (neg && size > SZINT) { /* negative number need sign extension? */ - for (i = SZINT; i < size; i++) /* correct extra bytes */ - buff[islittle ? i : size - 1 - i] = (char)MC; - } - luaL_addsize(b, size); /* add result to buffer */ -} - - -/* -** Copy 'size' bytes from 'src' to 'dest', correcting endianness if -** given 'islittle' is different from native endianness. -*/ -static void copywithendian (volatile char *dest, volatile const char *src, - int size, int islittle) { - if (islittle == nativeendian.little) { - while (size-- != 0) - *(dest++) = *(src++); - } - else { - dest += size - 1; - while (size-- != 0) - *(dest--) = *(src++); - } -} - - -static int str_pack (lua_State *L) { - luaL_Buffer b; - Header h; - const char *fmt = luaL_checkstring(L, 1); /* format string */ - int arg = 1; /* current argument to pack */ - size_t totalsize = 0; /* accumulate total size of result */ - initheader(L, &h); - lua_pushnil(L); /* mark to separate arguments from string buffer */ - luaL_buffinit(L, &b); - while (*fmt != '\0') { - int size, ntoalign; - KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); - totalsize += ntoalign + size; - while (ntoalign-- > 0) - luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ - arg++; - switch (opt) { - case Kint: { /* signed integers */ - lua_Integer n = luaL_checkinteger(L, arg); - if (size < SZINT) { /* need overflow check? */ - lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); - luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); - } - packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); - break; - } - case Kuint: { /* unsigned integers */ - lua_Integer n = luaL_checkinteger(L, arg); - if (size < SZINT) /* need overflow check? */ - luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), - arg, "unsigned overflow"); - packint(&b, (lua_Unsigned)n, h.islittle, size, 0); - break; - } - case Kfloat: { /* floating-point options */ - volatile Ftypes u; - char *buff = luaL_prepbuffsize(&b, size); - lua_Number n = luaL_checknumber(L, arg); /* get argument */ - if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ - else if (size == sizeof(u.d)) u.d = (double)n; - else u.n = n; - /* move 'u' to final result, correcting endianness if needed */ - copywithendian(buff, u.buff, size, h.islittle); - luaL_addsize(&b, size); - break; - } - case Kchar: { /* fixed-size string */ - size_t len; - const char *s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, len <= (size_t)size, arg, - "string longer than given size"); - luaL_addlstring(&b, s, len); /* add string */ - while (len++ < (size_t)size) /* pad extra space */ - luaL_addchar(&b, LUAL_PACKPADBYTE); - break; - } - case Kstring: { /* strings with length count */ - size_t len; - const char *s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, size >= (int)sizeof(size_t) || - len < ((size_t)1 << (size * NB)), - arg, "string length does not fit in given size"); - packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ - luaL_addlstring(&b, s, len); - totalsize += len; - break; - } - case Kzstr: { /* zero-terminated string */ - size_t len; - const char *s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); - luaL_addlstring(&b, s, len); - luaL_addchar(&b, '\0'); /* add zero at the end */ - totalsize += len + 1; - break; - } - case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ - case Kpaddalign: case Knop: - arg--; /* undo increment */ - break; - } - } - luaL_pushresult(&b); - return 1; -} - - -static int str_packsize (lua_State *L) { - Header h; - const char *fmt = luaL_checkstring(L, 1); /* format string */ - size_t totalsize = 0; /* accumulate total size of result */ - initheader(L, &h); - while (*fmt != '\0') { - int size, ntoalign; - KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); - size += ntoalign; /* total space used by option */ - luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, - "format result too large"); - totalsize += size; - switch (opt) { - case Kstring: /* strings with length count */ - case Kzstr: /* zero-terminated string */ - luaL_argerror(L, 1, "variable-length format"); - /* call never return, but to avoid warnings: *//* FALLTHROUGH */ - default: break; - } - } - lua_pushinteger(L, (lua_Integer)totalsize); - return 1; -} - - -/* -** Unpack an integer with 'size' bytes and 'islittle' endianness. -** If size is smaller than the size of a Lua integer and integer -** is signed, must do sign extension (propagating the sign to the -** higher bits); if size is larger than the size of a Lua integer, -** it must check the unread bytes to see whether they do not cause an -** overflow. -*/ -static lua_Integer unpackint (lua_State *L, const char *str, - int islittle, int size, int issigned) { - lua_Unsigned res = 0; - int i; - int limit = (size <= SZINT) ? size : SZINT; - for (i = limit - 1; i >= 0; i--) { - res <<= NB; - res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; - } - if (size < SZINT) { /* real size smaller than lua_Integer? */ - if (issigned) { /* needs sign extension? */ - lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); - res = ((res ^ mask) - mask); /* do sign extension */ - } - } - else if (size > SZINT) { /* must check unread bytes */ - int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; - for (i = limit; i < size; i++) { - if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) - luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); - } - } - return (lua_Integer)res; -} - - -static int str_unpack (lua_State *L) { - Header h; - const char *fmt = luaL_checkstring(L, 1); - size_t ld; - const char *data = luaL_checklstring(L, 2, &ld); - size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; - int n = 0; /* number of results */ - luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); - initheader(L, &h); - while (*fmt != '\0') { - int size, ntoalign; - KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); - if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) - luaL_argerror(L, 2, "data string too short"); - pos += ntoalign; /* skip alignment */ - /* stack space for item + next position */ - luaL_checkstack(L, 2, "too many results"); - n++; - switch (opt) { - case Kint: - case Kuint: { - lua_Integer res = unpackint(L, data + pos, h.islittle, size, - (opt == Kint)); - lua_pushinteger(L, res); - break; - } - case Kfloat: { - volatile Ftypes u; - lua_Number num; - copywithendian(u.buff, data + pos, size, h.islittle); - if (size == sizeof(u.f)) num = (lua_Number)u.f; - else if (size == sizeof(u.d)) num = (lua_Number)u.d; - else num = u.n; - lua_pushnumber(L, num); - break; - } - case Kchar: { - lua_pushlstring(L, data + pos, size); - break; - } - case Kstring: { - size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); - luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); - lua_pushlstring(L, data + pos + size, len); - pos += len; /* skip string */ - break; - } - case Kzstr: { - size_t len = (int)strlen(data + pos); - lua_pushlstring(L, data + pos, len); - pos += len + 1; /* skip string plus final '\0' */ - break; - } - case Kpaddalign: case Kpadding: case Knop: - n--; /* undo increment */ - break; - } - pos += size; - } - lua_pushinteger(L, pos + 1); /* next position */ - return n + 1; -} - -/* }====================================================== */ - - -static const luaL_Reg strlib[] = { - {"byte", str_byte}, - {"char", str_char}, - {"dump", str_dump}, - {"find", str_find}, - {"format", str_format}, - {"gmatch", gmatch}, - {"gsub", str_gsub}, - {"len", str_len}, - {"lower", str_lower}, - {"match", str_match}, - {"rep", str_rep}, - {"reverse", str_reverse}, - {"sub", str_sub}, - {"upper", str_upper}, - {"pack", str_pack}, - {"packsize", str_packsize}, - {"unpack", str_unpack}, - {NULL, NULL} -}; - - -static void createmetatable (lua_State *L) { - lua_createtable(L, 0, 1); /* table to be metatable for strings */ - lua_pushliteral(L, ""); /* dummy string */ - lua_pushvalue(L, -2); /* copy table */ - lua_setmetatable(L, -2); /* set table as metatable for strings */ - lua_pop(L, 1); /* pop dummy string */ - lua_pushvalue(L, -2); /* get string library */ - lua_setfield(L, -2, "__index"); /* metatable.__index = string */ - lua_pop(L, 1); /* pop metatable */ -} - - -/* -** Open string library -*/ -LUAMOD_API int luaopen_string (lua_State *L) { - luaL_newlib(L, strlib); - createmetatable(L); - return 1; -} - diff --git a/lib/compat53/ltablib.c b/lib/compat53/ltablib.c deleted file mode 100644 index c534957..0000000 --- a/lib/compat53/ltablib.c +++ /dev/null @@ -1,450 +0,0 @@ -/* -** $Id: ltablib.c,v 1.93.1.1 2017/04/19 17:20:42 roberto Exp $ -** Library for Table Manipulation -** See Copyright Notice in lua.h -*/ - -#define ltablib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include <limits.h> -#include <stddef.h> -#include <string.h> - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -/* -** Operations that an object must define to mimic a table -** (some functions only need some of them) -*/ -#define TAB_R 1 /* read */ -#define TAB_W 2 /* write */ -#define TAB_L 4 /* length */ -#define TAB_RW (TAB_R | TAB_W) /* read/write */ - - -#define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n)) - - -static int checkfield (lua_State *L, const char *key, int n) { - lua_pushstring(L, key); - return (lua_rawget(L, -n) != LUA_TNIL); -} - - -/* -** Check that 'arg' either is a table or can behave like one (that is, -** has a metatable with the required metamethods) -*/ -static void checktab (lua_State *L, int arg, int what) { - if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */ - int n = 1; /* number of elements to pop */ - if (lua_getmetatable(L, arg) && /* must have metatable */ - (!(what & TAB_R) || checkfield(L, "__index", ++n)) && - (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && - (!(what & TAB_L) || checkfield(L, "__len", ++n))) { - lua_pop(L, n); /* pop metatable and tested metamethods */ - } - else - luaL_checktype(L, arg, LUA_TTABLE); /* force an error */ - } -} - - -#if defined(LUA_COMPAT_MAXN) -static int maxn (lua_State *L) { - lua_Number max = 0; - luaL_checktype(L, 1, LUA_TTABLE); - lua_pushnil(L); /* first key */ - while (lua_next(L, 1)) { - lua_pop(L, 1); /* remove value */ - if (lua_type(L, -1) == LUA_TNUMBER) { - lua_Number v = lua_tonumber(L, -1); - if (v > max) max = v; - } - } - lua_pushnumber(L, max); - return 1; -} -#endif - - -static int tinsert (lua_State *L) { - lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ - lua_Integer pos; /* where to insert new element */ - switch (lua_gettop(L)) { - case 2: { /* called with only 2 arguments */ - pos = e; /* insert new element at the end */ - break; - } - case 3: { - lua_Integer i; - pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ - luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); - for (i = e; i > pos; i--) { /* move up elements */ - lua_geti(L, 1, i - 1); - lua_seti(L, 1, i); /* t[i] = t[i - 1] */ - } - break; - } - default: { - return luaL_error(L, "wrong number of arguments to 'insert'"); - } - } - lua_seti(L, 1, pos); /* t[pos] = v */ - return 0; -} - - -static int tremove (lua_State *L) { - lua_Integer size = aux_getn(L, 1, TAB_RW); - lua_Integer pos = luaL_optinteger(L, 2, size); - if (pos != size) /* validate 'pos' if given */ - luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); - lua_geti(L, 1, pos); /* result = t[pos] */ - for ( ; pos < size; pos++) { - lua_geti(L, 1, pos + 1); - lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ - } - lua_pushnil(L); - lua_seti(L, 1, pos); /* t[pos] = nil */ - return 1; -} - - -/* -** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever -** possible, copy in increasing order, which is better for rehashing. -** "possible" means destination after original range, or smaller -** than origin, or copying to another table. -*/ -static int tmove (lua_State *L) { - lua_Integer f = luaL_checkinteger(L, 2); - lua_Integer e = luaL_checkinteger(L, 3); - lua_Integer t = luaL_checkinteger(L, 4); - int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ - checktab(L, 1, TAB_R); - checktab(L, tt, TAB_W); - if (e >= f) { /* otherwise, nothing to move */ - lua_Integer n, i; - luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, - "too many elements to move"); - n = e - f + 1; /* number of elements to move */ - luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, - "destination wrap around"); - if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { - for (i = 0; i < n; i++) { - lua_geti(L, 1, f + i); - lua_seti(L, tt, t + i); - } - } - else { - for (i = n - 1; i >= 0; i--) { - lua_geti(L, 1, f + i); - lua_seti(L, tt, t + i); - } - } - } - lua_pushvalue(L, tt); /* return destination table */ - return 1; -} - - -static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { - lua_geti(L, 1, i); - if (!lua_isstring(L, -1)) - luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", - luaL_typename(L, -1), i); - luaL_addvalue(b); -} - - -static int tconcat (lua_State *L) { - luaL_Buffer b; - lua_Integer last = aux_getn(L, 1, TAB_R); - size_t lsep; - const char *sep = luaL_optlstring(L, 2, "", &lsep); - lua_Integer i = luaL_optinteger(L, 3, 1); - last = luaL_optinteger(L, 4, last); - luaL_buffinit(L, &b); - for (; i < last; i++) { - addfield(L, &b, i); - luaL_addlstring(&b, sep, lsep); - } - if (i == last) /* add last value (if interval was not empty) */ - addfield(L, &b, i); - luaL_pushresult(&b); - return 1; -} - - -/* -** {====================================================== -** Pack/unpack -** ======================================================= -*/ - -static int pack (lua_State *L) { - int i; - int n = lua_gettop(L); /* number of elements to pack */ - lua_createtable(L, n, 1); /* create result table */ - lua_insert(L, 1); /* put it at index 1 */ - for (i = n; i >= 1; i--) /* assign elements */ - lua_seti(L, 1, i); - lua_pushinteger(L, n); - lua_setfield(L, 1, "n"); /* t.n = number of elements */ - return 1; /* return table */ -} - - -static int unpack (lua_State *L) { - lua_Unsigned n; - lua_Integer i = luaL_optinteger(L, 2, 1); - lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); - if (i > e) return 0; /* empty range */ - n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ - if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) - return luaL_error(L, "too many results to unpack"); - for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */ - lua_geti(L, 1, i); - } - lua_geti(L, 1, e); /* push last element */ - return (int)n; -} - -/* }====================================================== */ - - - -/* -** {====================================================== -** Quicksort -** (based on 'Algorithms in MODULA-3', Robert Sedgewick; -** Addison-Wesley, 1993.) -** ======================================================= -*/ - - -/* type for array indices */ -typedef unsigned int IdxT; - - -/* -** Produce a "random" 'unsigned int' to randomize pivot choice. This -** macro is used only when 'sort' detects a big imbalance in the result -** of a partition. (If you don't want/need this "randomness", ~0 is a -** good choice.) -*/ -#if !defined(l_randomizePivot) /* { */ - -#include <time.h> - -/* size of 'e' measured in number of 'unsigned int's */ -#define sof(e) (sizeof(e) / sizeof(unsigned int)) - -/* -** Use 'time' and 'clock' as sources of "randomness". Because we don't -** know the types 'clock_t' and 'time_t', we cannot cast them to -** anything without risking overflows. A safe way to use their values -** is to copy them to an array of a known type and use the array values. -*/ -static unsigned int l_randomizePivot (void) { - clock_t c = clock(); - time_t t = time(NULL); - unsigned int buff[sof(c) + sof(t)]; - unsigned int i, rnd = 0; - memcpy(buff, &c, sof(c) * sizeof(unsigned int)); - memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int)); - for (i = 0; i < sof(buff); i++) - rnd += buff[i]; - return rnd; -} - -#endif /* } */ - - -/* arrays larger than 'RANLIMIT' may use randomized pivots */ -#define RANLIMIT 100u - - -static void set2 (lua_State *L, IdxT i, IdxT j) { - lua_seti(L, 1, i); - lua_seti(L, 1, j); -} - - -/* -** Return true iff value at stack index 'a' is less than the value at -** index 'b' (according to the order of the sort). -*/ -static int sort_comp (lua_State *L, int a, int b) { - if (lua_isnil(L, 2)) /* no function? */ - return lua_compare(L, a, b, LUA_OPLT); /* a < b */ - else { /* function */ - int res; - lua_pushvalue(L, 2); /* push function */ - lua_pushvalue(L, a-1); /* -1 to compensate function */ - lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ - lua_call(L, 2, 1); /* call function */ - res = lua_toboolean(L, -1); /* get result */ - lua_pop(L, 1); /* pop result */ - return res; - } -} - - -/* -** Does the partition: Pivot P is at the top of the stack. -** precondition: a[lo] <= P == a[up-1] <= a[up], -** so it only needs to do the partition from lo + 1 to up - 2. -** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] -** returns 'i'. -*/ -static IdxT partition (lua_State *L, IdxT lo, IdxT up) { - IdxT i = lo; /* will be incremented before first use */ - IdxT j = up - 1; /* will be decremented before first use */ - /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ - for (;;) { - /* next loop: repeat ++i while a[i] < P */ - while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { - if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ - luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[i] */ - } - /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ - /* next loop: repeat --j while P < a[j] */ - while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { - if (j < i) /* j < i but a[j] > P ?? */ - luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[j] */ - } - /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ - if (j < i) { /* no elements out of place? */ - /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ - lua_pop(L, 1); /* pop a[j] */ - /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ - set2(L, up - 1, i); - return i; - } - /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ - set2(L, i, j); - } -} - - -/* -** Choose an element in the middle (2nd-3th quarters) of [lo,up] -** "randomized" by 'rnd' -*/ -static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { - IdxT r4 = (up - lo) / 4; /* range/4 */ - IdxT p = rnd % (r4 * 2) + (lo + r4); - lua_assert(lo + r4 <= p && p <= up - r4); - return p; -} - - -/* -** QuickSort algorithm (recursive function) -*/ -static void auxsort (lua_State *L, IdxT lo, IdxT up, - unsigned int rnd) { - while (lo < up) { /* loop for tail recursion */ - IdxT p; /* Pivot index */ - IdxT n; /* to be used later */ - /* sort elements 'lo', 'p', and 'up' */ - lua_geti(L, 1, lo); - lua_geti(L, 1, up); - if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ - set2(L, lo, up); /* swap a[lo] - a[up] */ - else - lua_pop(L, 2); /* remove both values */ - if (up - lo == 1) /* only 2 elements? */ - return; /* already sorted */ - if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */ - p = (lo + up)/2; /* middle element is a good pivot */ - else /* for larger intervals, it is worth a random pivot */ - p = choosePivot(lo, up, rnd); - lua_geti(L, 1, p); - lua_geti(L, 1, lo); - if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */ - set2(L, p, lo); /* swap a[p] - a[lo] */ - else { - lua_pop(L, 1); /* remove a[lo] */ - lua_geti(L, 1, up); - if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */ - set2(L, p, up); /* swap a[up] - a[p] */ - else - lua_pop(L, 2); - } - if (up - lo == 2) /* only 3 elements? */ - return; /* already sorted */ - lua_geti(L, 1, p); /* get middle element (Pivot) */ - lua_pushvalue(L, -1); /* push Pivot */ - lua_geti(L, 1, up - 1); /* push a[up - 1] */ - set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ - p = partition(L, lo, up); - /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ - if (p - lo < up - p) { /* lower interval is smaller? */ - auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */ - n = p - lo; /* size of smaller interval */ - lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */ - } - else { - auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */ - n = up - p; /* size of smaller interval */ - up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */ - } - if ((up - lo) / 128 > n) /* partition too imbalanced? */ - rnd = l_randomizePivot(); /* try a new randomization */ - } /* tail call auxsort(L, lo, up, rnd) */ -} - - -static int sort (lua_State *L) { - lua_Integer n = aux_getn(L, 1, TAB_RW); - if (n > 1) { /* non-trivial interval? */ - luaL_argcheck(L, n < INT_MAX, 1, "array too big"); - if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ - luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ - lua_settop(L, 2); /* make sure there are two arguments */ - auxsort(L, 1, (IdxT)n, 0); - } - return 0; -} - -/* }====================================================== */ - - -static const luaL_Reg tab_funcs[] = { - {"concat", tconcat}, -#if defined(LUA_COMPAT_MAXN) - {"maxn", maxn}, -#endif - {"insert", tinsert}, - {"pack", pack}, - {"unpack", unpack}, - {"remove", tremove}, - {"move", tmove}, - {"sort", sort}, - {NULL, NULL} -}; - - -LUAMOD_API int luaopen_table (lua_State *L) { - luaL_newlib(L, tab_funcs); -#if defined(LUA_COMPAT_UNPACK) - /* _G.unpack = table.unpack */ - lua_getfield(L, -1, "unpack"); - lua_setglobal(L, "unpack"); -#endif - return 1; -} - diff --git a/lib/compat53/lutf8lib.c b/lib/compat53/lutf8lib.c deleted file mode 100644 index 10bd238..0000000 --- a/lib/compat53/lutf8lib.c +++ /dev/null @@ -1,256 +0,0 @@ -/* -** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $ -** Standard library for UTF-8 manipulation -** See Copyright Notice in lua.h -*/ - -#define lutf8lib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include <assert.h> -#include <limits.h> -#include <stdlib.h> -#include <string.h> - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - -#define MAXUNICODE 0x10FFFF - -#define iscont(p) ((*(p) & 0xC0) == 0x80) - - -/* from strlib */ -/* translate a relative string position: negative means back from end */ -static lua_Integer u_posrelat (lua_Integer pos, size_t len) { - if (pos >= 0) return pos; - else if (0u - (size_t)pos > len) return 0; - else return (lua_Integer)len + pos + 1; -} - - -/* -** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. -*/ -static const char *utf8_decode (const char *o, int *val) { - static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; - const unsigned char *s = (const unsigned char *)o; - unsigned int c = s[0]; - unsigned int res = 0; /* final result */ - if (c < 0x80) /* ascii? */ - res = c; - else { - int count = 0; /* to count number of continuation bytes */ - while (c & 0x40) { /* still have continuation bytes? */ - int cc = s[++count]; /* read next byte */ - if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ - return NULL; /* invalid byte sequence */ - res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ - c <<= 1; /* to test next bit */ - } - res |= ((c & 0x7F) << (count * 5)); /* add first byte */ - if (count > 3 || res > MAXUNICODE || res <= limits[count]) - return NULL; /* invalid byte sequence */ - s += count; /* skip continuation bytes read */ - } - if (val) *val = res; - return (const char *)s + 1; /* +1 to include first byte */ -} - - -/* -** utf8len(s [, i [, j]]) --> number of characters that start in the -** range [i,j], or nil + current position if 's' is not well formed in -** that interval -*/ -static int utflen (lua_State *L) { - int n = 0; - size_t len; - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); - lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); - luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, - "initial position out of string"); - luaL_argcheck(L, --posj < (lua_Integer)len, 3, - "final position out of string"); - while (posi <= posj) { - const char *s1 = utf8_decode(s + posi, NULL); - if (s1 == NULL) { /* conversion error? */ - lua_pushnil(L); /* return nil ... */ - lua_pushinteger(L, posi + 1); /* ... and current position */ - return 2; - } - posi = s1 - s; - n++; - } - lua_pushinteger(L, n); - return 1; -} - - -/* -** codepoint(s, [i, [j]]) -> returns codepoints for all characters -** that start in the range [i,j] -*/ -static int codepoint (lua_State *L) { - size_t len; - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); - lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); - int n; - const char *se; - luaL_argcheck(L, posi >= 1, 2, "out of range"); - luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); - if (posi > pose) return 0; /* empty interval; return no values */ - if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ - return luaL_error(L, "string slice too long"); - n = (int)(pose - posi) + 1; - luaL_checkstack(L, n, "string slice too long"); - n = 0; - se = s + pose; - for (s += posi - 1; s < se;) { - int code; - s = utf8_decode(s, &code); - if (s == NULL) - return luaL_error(L, "invalid UTF-8 code"); - lua_pushinteger(L, code); - n++; - } - return n; -} - - -static void pushutfchar (lua_State *L, int arg) { - lua_Integer code = luaL_checkinteger(L, arg); - luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); - lua_pushfstring(L, "%U", (long)code); -} - - -/* -** utfchar(n1, n2, ...) -> char(n1)..char(n2)... -*/ -static int utfchar (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - if (n == 1) /* optimize common case of single char */ - pushutfchar(L, 1); - else { - int i; - luaL_Buffer b; - luaL_buffinit(L, &b); - for (i = 1; i <= n; i++) { - pushutfchar(L, i); - luaL_addvalue(&b); - } - luaL_pushresult(&b); - } - return 1; -} - - -/* -** offset(s, n, [i]) -> index where n-th character counting from -** position 'i' starts; 0 means character at 'i'. -*/ -static int byteoffset (lua_State *L) { - size_t len; - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer n = luaL_checkinteger(L, 2); - lua_Integer posi = (n >= 0) ? 1 : len + 1; - posi = u_posrelat(luaL_optinteger(L, 3, posi), len); - luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, - "position out of range"); - if (n == 0) { - /* find beginning of current byte sequence */ - while (posi > 0 && iscont(s + posi)) posi--; - } - else { - if (iscont(s + posi)) - return luaL_error(L, "initial position is a continuation byte"); - if (n < 0) { - while (n < 0 && posi > 0) { /* move back */ - do { /* find beginning of previous character */ - posi--; - } while (posi > 0 && iscont(s + posi)); - n++; - } - } - else { - n--; /* do not move for 1st character */ - while (n > 0 && posi < (lua_Integer)len) { - do { /* find beginning of next character */ - posi++; - } while (iscont(s + posi)); /* (cannot pass final '\0') */ - n--; - } - } - } - if (n == 0) /* did it find given character? */ - lua_pushinteger(L, posi + 1); - else /* no such character */ - lua_pushnil(L); - return 1; -} - - -static int iter_aux (lua_State *L) { - size_t len; - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer n = lua_tointeger(L, 2) - 1; - if (n < 0) /* first iteration? */ - n = 0; /* start from here */ - else if (n < (lua_Integer)len) { - n++; /* skip current byte */ - while (iscont(s + n)) n++; /* and its continuations */ - } - if (n >= (lua_Integer)len) - return 0; /* no more codepoints */ - else { - int code; - const char *next = utf8_decode(s + n, &code); - if (next == NULL || iscont(next)) - return luaL_error(L, "invalid UTF-8 code"); - lua_pushinteger(L, n + 1); - lua_pushinteger(L, code); - return 2; - } -} - - -static int iter_codes (lua_State *L) { - luaL_checkstring(L, 1); - lua_pushcfunction(L, iter_aux); - lua_pushvalue(L, 1); - lua_pushinteger(L, 0); - return 3; -} - - -/* pattern to match a single UTF-8 character */ -#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" - - -static const luaL_Reg funcs[] = { - {"offset", byteoffset}, - {"codepoint", codepoint}, - {"char", utfchar}, - {"len", utflen}, - {"codes", iter_codes}, - /* placeholders */ - {"charpattern", NULL}, - {NULL, NULL} -}; - - -LUAMOD_API int luaopen_utf8 (lua_State *L) { - luaL_newlib(L, funcs); - lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); - lua_setfield(L, -2, "charpattern"); - return 1; -} - diff --git a/lib/compat53/rockspecs/bit32-5.3.5-1.rockspec b/lib/compat53/rockspecs/bit32-5.3.5-1.rockspec deleted file mode 100644 index 353e19c..0000000 --- a/lib/compat53/rockspecs/bit32-5.3.5-1.rockspec +++ /dev/null @@ -1,28 +0,0 @@ -package = "bit32" -version = "5.3.5-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.9.zip", - dir = "lua-compat-5.3-0.9", -} -description = { - summary = "Lua 5.2 bit manipulation library", - detailed = [[ - bit32 is the native Lua 5.2 bit manipulation library, in the version - from Lua 5.3; it is compatible with Lua 5.1, 5.2 and 5.3. - ]], - homepage = "http://www.lua.org/manual/5.2/manual.html#6.7", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5" -} -build = { - type = "builtin", - modules = { - bit32 = { - sources = { "lbitlib.c" }, - defines = { "LUA_COMPAT_BITLIB" }, - incdirs = { "c-api" }, - } - } -} diff --git a/lib/compat53/rockspecs/bit32-5.3.5.1-1.rockspec b/lib/compat53/rockspecs/bit32-5.3.5.1-1.rockspec deleted file mode 100644 index 371f1ae..0000000 --- a/lib/compat53/rockspecs/bit32-5.3.5.1-1.rockspec +++ /dev/null @@ -1,28 +0,0 @@ -package = "bit32" -version = "5.3.5.1-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.10.zip", - dir = "lua-compat-5.3-0.10", -} -description = { - summary = "Lua 5.2 bit manipulation library", - detailed = [[ - bit32 is the native Lua 5.2 bit manipulation library, in the version - from Lua 5.3; it is compatible with Lua 5.1, 5.2, 5.3 and 5.4. - ]], - homepage = "http://www.lua.org/manual/5.2/manual.html#6.7", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5" -} -build = { - type = "builtin", - modules = { - bit32 = { - sources = { "lbitlib.c" }, - defines = { "LUA_COMPAT_BITLIB" }, - incdirs = { "c-api" }, - } - } -} diff --git a/lib/compat53/rockspecs/bit32-scm-1.rockspec b/lib/compat53/rockspecs/bit32-scm-1.rockspec deleted file mode 100644 index 78f9736..0000000 --- a/lib/compat53/rockspecs/bit32-scm-1.rockspec +++ /dev/null @@ -1,28 +0,0 @@ -package = "bit32" -version = "scm-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/master.zip", - dir = "lua-compat-5.3-master", -} -description = { - summary = "Lua 5.2 bit manipulation library", - detailed = [[ - bit32 is the native Lua 5.2 bit manipulation library, in the version - from Lua 5.3; it is compatible with Lua 5.1, 5.2 and 5.3. - ]], - homepage = "http://www.lua.org/manual/5.2/manual.html#6.7", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5" -} -build = { - type = "builtin", - modules = { - bit32 = { - sources = { "lbitlib.c" }, - defines = { "LUA_COMPAT_BITLIB" }, - incdirs = { "c-api" }, - } - } -} diff --git a/lib/compat53/rockspecs/compat53-0.1-1.rockspec b/lib/compat53/rockspecs/compat53-0.1-1.rockspec deleted file mode 100644 index b9012fe..0000000 --- a/lib/compat53/rockspecs/compat53-0.1-1.rockspec +++ /dev/null @@ -1,31 +0,0 @@ -package = "compat53" -version = "0.1-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.1.zip", - dir = "lua-compat-5.3-0.1", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.4", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53"] = "compat53.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - } -} - diff --git a/lib/compat53/rockspecs/compat53-0.11-1.rockspec b/lib/compat53/rockspecs/compat53-0.11-1.rockspec deleted file mode 100644 index 9608f0a..0000000 --- a/lib/compat53/rockspecs/compat53-0.11-1.rockspec +++ /dev/null @@ -1,33 +0,0 @@ -package = "compat53" -version = "0.11-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.11.zip", - dir = "lua-compat-5.3-0.11", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.module"] = "compat53/module.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - ["compat53.io"] = "liolib.c", - } -} - diff --git a/lib/compat53/rockspecs/compat53-0.12-1.rockspec b/lib/compat53/rockspecs/compat53-0.12-1.rockspec deleted file mode 100644 index 1b120ca..0000000 --- a/lib/compat53/rockspecs/compat53-0.12-1.rockspec +++ /dev/null @@ -1,33 +0,0 @@ -package = "compat53" -version = "0.12-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.12.zip", - dir = "lua-compat-5.3-0.12", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.module"] = "compat53/module.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - ["compat53.io"] = "liolib.c", - } -} - diff --git a/lib/compat53/rockspecs/compat53-0.13-1.rockspec b/lib/compat53/rockspecs/compat53-0.13-1.rockspec deleted file mode 100644 index f08dc66..0000000 --- a/lib/compat53/rockspecs/compat53-0.13-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.13-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.13.zip", - dir = "lua-compat-5.3-0.13" -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5" - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.io"] = "liolib.c", - ["compat53.module"] = "compat53/module.lua", - ["compat53.string"] = "lstrlib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.utf8"] = "lutf8lib.c" - } -} diff --git a/lib/compat53/rockspecs/compat53-0.14-1.rockspec b/lib/compat53/rockspecs/compat53-0.14-1.rockspec deleted file mode 100644 index 54ad4a9..0000000 --- a/lib/compat53/rockspecs/compat53-0.14-1.rockspec +++ /dev/null @@ -1,33 +0,0 @@ -package = "compat53" -version = "0.14-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.14.zip", - dir = "lua-compat-5.3-0.14" -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5" - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.file_mt"] = "compat53/file_mt.lua", - ["compat53.init"] = "compat53/init.lua", - ["compat53.io"] = "liolib.c", - ["compat53.module"] = "compat53/module.lua", - ["compat53.string"] = "lstrlib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.utf8"] = "lutf8lib.c" - } -} diff --git a/lib/compat53/rockspecs/compat53-0.14.1-1.rockspec b/lib/compat53/rockspecs/compat53-0.14.1-1.rockspec deleted file mode 100644 index ea35bb2..0000000 --- a/lib/compat53/rockspecs/compat53-0.14.1-1.rockspec +++ /dev/null @@ -1,33 +0,0 @@ -package = "compat53" -version = "0.14.1-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.14.1.zip", - dir = "lua-compat-5.3-0.14.1" -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5" - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.file_mt"] = "compat53/file_mt.lua", - ["compat53.init"] = "compat53/init.lua", - ["compat53.io"] = "liolib.c", - ["compat53.module"] = "compat53/module.lua", - ["compat53.string"] = "lstrlib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.utf8"] = "lutf8lib.c" - } -} diff --git a/lib/compat53/rockspecs/compat53-0.14.2-1.rockspec b/lib/compat53/rockspecs/compat53-0.14.2-1.rockspec deleted file mode 100644 index 99236fe..0000000 --- a/lib/compat53/rockspecs/compat53-0.14.2-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.14.2-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.14.2.zip", - dir = "lua-compat-5.3-0.14.2" -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5" -} -build = { - type = "builtin", - modules = { - ["compat53.file_mt"] = "compat53/file_mt.lua", - ["compat53.init"] = "compat53/init.lua", - ["compat53.io"] = "liolib.c", - ["compat53.module"] = "compat53/module.lua", - ["compat53.string"] = "lstrlib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.utf8"] = "lutf8lib.c" - } -} diff --git a/lib/compat53/rockspecs/compat53-0.14.3-1.rockspec b/lib/compat53/rockspecs/compat53-0.14.3-1.rockspec deleted file mode 100644 index d6327d7..0000000 --- a/lib/compat53/rockspecs/compat53-0.14.3-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.14.3-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.14.3.zip", - dir = "lua-compat-5.3-0.14.3" -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5" -} -build = { - type = "builtin", - modules = { - ["compat53.file_mt"] = "compat53/file_mt.lua", - ["compat53.init"] = "compat53/init.lua", - ["compat53.io"] = "liolib.c", - ["compat53.module"] = "compat53/module.lua", - ["compat53.string"] = "lstrlib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.utf8"] = "lutf8lib.c" - } -} diff --git a/lib/compat53/rockspecs/compat53-0.14.4-1.rockspec b/lib/compat53/rockspecs/compat53-0.14.4-1.rockspec deleted file mode 100644 index 804220f..0000000 --- a/lib/compat53/rockspecs/compat53-0.14.4-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.14.4-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.14.4.zip", - dir = "lua-compat-5.3-0.14.4" -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5" -} -build = { - type = "builtin", - modules = { - ["compat53.file_mt"] = "compat53/file_mt.lua", - ["compat53.init"] = "compat53/init.lua", - ["compat53.io"] = "liolib.c", - ["compat53.module"] = "compat53/module.lua", - ["compat53.string"] = "lstrlib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.utf8"] = "lutf8lib.c" - } -} diff --git a/lib/compat53/rockspecs/compat53-0.2-1.rockspec b/lib/compat53/rockspecs/compat53-0.2-1.rockspec deleted file mode 100644 index 47ddaf2..0000000 --- a/lib/compat53/rockspecs/compat53-0.2-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.2-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.2.zip", - dir = "lua-compat-5.3-0.2", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.4", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.module"] = "compat53/module.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - } -} - diff --git a/lib/compat53/rockspecs/compat53-0.3-1.rockspec b/lib/compat53/rockspecs/compat53-0.3-1.rockspec deleted file mode 100644 index d99099f..0000000 --- a/lib/compat53/rockspecs/compat53-0.3-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.3-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.3.zip", - dir = "lua-compat-5.3-0.3", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.4", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.module"] = "compat53/module.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - } -} - diff --git a/lib/compat53/rockspecs/compat53-0.4-1.rockspec b/lib/compat53/rockspecs/compat53-0.4-1.rockspec deleted file mode 100644 index bc33826..0000000 --- a/lib/compat53/rockspecs/compat53-0.4-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.4-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.4.zip", - dir = "lua-compat-5.3-0.4", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.4", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.module"] = "compat53/module.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - } -} - diff --git a/lib/compat53/rockspecs/compat53-0.5-1.rockspec b/lib/compat53/rockspecs/compat53-0.5-1.rockspec deleted file mode 100644 index 8d18b51..0000000 --- a/lib/compat53/rockspecs/compat53-0.5-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.5-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.5.zip", - dir = "lua-compat-5.3-0.5", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.4", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.module"] = "compat53/module.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - } -} - diff --git a/lib/compat53/rockspecs/compat53-0.7-1.rockspec b/lib/compat53/rockspecs/compat53-0.7-1.rockspec deleted file mode 100644 index fc5a0c8..0000000 --- a/lib/compat53/rockspecs/compat53-0.7-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.7-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.7.zip", - dir = "lua-compat-5.3-0.7", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.4", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.module"] = "compat53/module.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - } -} - diff --git a/lib/compat53/rockspecs/compat53-0.8-1.rockspec b/lib/compat53/rockspecs/compat53-0.8-1.rockspec deleted file mode 100644 index 2fe47b9..0000000 --- a/lib/compat53/rockspecs/compat53-0.8-1.rockspec +++ /dev/null @@ -1,32 +0,0 @@ -package = "compat53" -version = "0.8-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.8.zip", - dir = "lua-compat-5.3-0.8", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.module"] = "compat53/module.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - } -} - diff --git a/lib/compat53/rockspecs/compat53-scm-1.rockspec b/lib/compat53/rockspecs/compat53-scm-1.rockspec deleted file mode 100644 index b0581f9..0000000 --- a/lib/compat53/rockspecs/compat53-scm-1.rockspec +++ /dev/null @@ -1,34 +0,0 @@ -package = "compat53" -version = "scm-1" -source = { - url = "https://github.com/lunarmodules/lua-compat-5.3/archive/master.zip", - dir = "lua-compat-5.3-master", -} -description = { - summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", - detailed = [[ - This is a small module that aims to make it easier to write Lua - code in a Lua-5.3-style that runs on Lua 5.1+. - It does *not* make Lua 5.2 (or even 5.1) entirely compatible - with Lua 5.3, but it brings the API closer to that of Lua 5.3. - ]], - homepage = "https://github.com/lunarmodules/lua-compat-5.3", - license = "MIT" -} -dependencies = { - "lua >= 5.1, < 5.5", - --"struct" -- make Roberto's struct module optional -} -build = { - type = "builtin", - modules = { - ["compat53.init"] = "compat53/init.lua", - ["compat53.module"] = "compat53/module.lua", - ["compat53.file_mt"] = "compat53/file_mt.lua", - ["compat53.utf8"] = "lutf8lib.c", - ["compat53.table"] = "ltablib.c", - ["compat53.string"] = "lstrlib.c", - ["compat53.io"] = "liolib.c", - } -} - diff --git a/lib/compat53/tests/test-bit32.lua b/lib/compat53/tests/test-bit32.lua deleted file mode 100755 index a408b7d..0000000 --- a/lib/compat53/tests/test-bit32.lua +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env lua - -local bit32 = require("bit32") - - -assert(bit32.bnot(0) == 2^32-1) -assert(bit32.bnot(-1) == 0) -assert(bit32.band(1, 3, 5) == 1) -assert(bit32.bor(1, 3, 5) == 7) - diff --git a/lib/compat53/tests/test.lua b/lib/compat53/tests/test.lua deleted file mode 100755 index 503e3f4..0000000 --- a/lib/compat53/tests/test.lua +++ /dev/null @@ -1,866 +0,0 @@ -#!/usr/bin/env lua - -local F, tproxy, writefile, noprint, ___ -do - local type, unpack = type, table.unpack or unpack - local assert, io = assert, io - function F(...) - local args, n = { ... }, select('#', ...) - for i = 1, n do - local t = type(args[i]) - if t ~= "string" and t ~= "number" and t ~= "boolean" then - args[i] = t - end - end - return unpack(args, 1, n) - end - function tproxy(t) - return setmetatable({}, { - __index = t, - __newindex = t, - __len = function() return #t end, - }), t - end - function writefile(name, contents, bin) - local f = assert(io.open(name, bin and "wb" or "w")) - f:write(contents) - f:close() - end - function noprint() end - local sep = ("="):rep(70) - function ___() - print(sep) - end -end - -local V = _VERSION:gsub("^.*(%d+)%.(%d+)$", "%1%2") -if jit then V = "jit" end - -local is_puclua51 = (_VERSION == "Lua 5.1" and not jit) - -local mode = "global" -if arg[1] == "module" then - mode = "module" -end -local self = arg[0] - -package.path = "../?.lua;../?/init.lua" -package.cpath = "./?-"..V..".so;./?-"..V..".dll;./?.so;./?.dll" -if mode == "module" then - print("testing Lua API using `compat53.module` ...") - _ENV = require("compat53.module") - if setfenv then setfenv(1, _ENV) end -else - print("testing Lua API using `compat53` ...") - require("compat53") -end - - -___'' -do - print("assert", F(pcall(assert, false))) - print("assert", F(pcall(assert, false, nil))) - print("assert", F(pcall(assert, false, "error msg"))) - print("assert", F(pcall(assert, nil, {}))) - print("assert", F(pcall(assert, 1, 2, 3))) -end - - -___'' -do - local t = setmetatable({}, { __index = { 1, false, "three" } }) - for i,v in ipairs(t) do - print("ipairs", i, v) - end -end - - -___'' -do - local p, t = tproxy{ "a", "b", "c" } - print("table.concat", table.concat(p)) - print("table.concat", table.concat(p, ",", 2)) - print("table.concat", table.concat(p, ".", 1, 2)) - print("table.concat", table.concat(t)) - print("table.concat", table.concat(t, ",", 2)) - print("table.concat", table.concat(t, ".", 1, 2)) -end - - -___'' -do - local p, t = tproxy{ "a", "b", "c" } - table.insert(p, "d") - print("table.insert", next(p), t[4]) - table.insert(p, 1, "z") - print("table.insert", next(p), t[1], t[2]) - table.insert(p, 2, "y") - print("table.insert", next(p), t[1], t[2], p[3]) - t = { "a", "b", "c" } - table.insert(t, "d") - print("table.insert", t[1], t[2], t[3], t[4]) - table.insert(t, 1, "z") - print("table.insert", t[1], t[2], t[3], t[4], t[5]) - table.insert(t, 2, "y") - print("table.insert", t[1], t[2], t[3], t[4], t[5]) -end - - -___'' -do - local ps, s = tproxy{ "a", "b", "c", "d" } - local pd, d = tproxy{ "A", "B", "C", "D" } - table.move(ps, 1, 4, 1, pd) - print("table.move", next(pd), d[1], d[2], d[3], d[4]) - pd, d = tproxy{ "A", "B", "C", "D" } - table.move(ps, 2, 4, 1, pd) - print("table.move", next(pd), d[1], d[2], d[3], d[4]) - pd, d = tproxy{ "A", "B", "C", "D" } - table.move(ps, 2, 3, 4, pd) - print("table.move", next(pd), d[1], d[2], d[3], d[4], d[5]) - table.move(ps, 2, 4, 1) - print("table.move", next(ps), s[1], s[2], s[3], s[4]) - ps, s = tproxy{ "a", "b", "c", "d" } - table.move(ps, 2, 3, 4) - print("table.move", next(ps), s[1], s[2], s[3], s[4], s[5]) - s = { "a", "b", "c", "d" } - d = { "A", "B", "C", "D" } - table.move(s, 1, 4, 1, d) - print("table.move", d[1], d[2], d[3], d[4]) - d = { "A", "B", "C", "D" } - table.move(s, 2, 4, 1, d) - print("table.move", d[1], d[2], d[3], d[4]) - d = { "A", "B", "C", "D" } - table.move(s, 2, 3, 4, d) - print("table.move", d[1], d[2], d[3], d[4], d[5]) - table.move(s, 2, 4, 1) - print("table.move", s[1], s[2], s[3], s[4]) - s = { "a", "b", "c", "d" } - table.move(s, 2, 3, 4) - print("table.move", s[1], s[2], s[3], s[4], s[5]) -end - - -___'' -do - local p, t = tproxy{ "a", "b", "c", "d", "e" } - print("table.remove", table.remove(p)) - print("table.remove", next(p), t[1], t[2], t[3], t[4], t[5]) - print("table.remove", table.remove(p, 1)) - print("table.remove", next(p), t[1], t[2], t[3], t[4]) - print("table.remove", table.remove(p, 2)) - print("table.remove", next(p), t[1], t[2], t[3]) - print("table.remove", table.remove(p, 3)) - print("table.remove", next(p), t[1], t[2], t[3]) - p, t = tproxy{} - print("table.remove", table.remove(p)) - print("table.remove", next(p), next(t)) - t = { "a", "b", "c", "d", "e" } - print("table.remove", table.remove(t)) - print("table.remove", t[1], t[2], t[3], t[4], t[5]) - print("table.remove", table.remove(t, 1)) - print("table.remove", t[1], t[2], t[3], t[4]) - print("table.remove", table.remove(t, 2)) - print("table.remove", t[1], t[2], t[3]) - print("table.remove", table.remove(t, 3)) - print("table.remove", t[1], t[2], t[3]) - t = {} - print("table.remove", table.remove(t)) - print("table.remove", next(t)) -end - -___'' -do - local p, t = tproxy{ 3, 1, 5, 2, 8, 5, 2, 9, 7, 4 } - table.sort(p) - print("table.sort", next(p)) - for i,v in ipairs(t) do - print("table.sort", i, v) - end - table.sort(p) - print("table.sort", next(p)) - for i,v in ipairs(t) do - print("table.sort", i, v) - end - p, t = tproxy{ 9, 8, 7, 6, 5, 4, 3, 2, 1 } - table.sort(p) - print("table.sort", next(p)) - for i,v in ipairs(t) do - print("table.sort", i, v) - end - table.sort(p, function(a, b) return a > b end) - print("table.sort", next(p)) - for i,v in ipairs(t) do - print("table.sort", i, v) - end - p, t = tproxy{ 1, 1, 1, 1, 1 } - print("table.sort", next(p)) - for i,v in ipairs(t) do - print("table.sort", i, v) - end - t = { 3, 1, 5, 2, 8, 5, 2, 9, 7, 4 } - table.sort(t) - for i,v in ipairs(t) do - print("table.sort", i, v) - end - table.sort(t, function(a, b) return a > b end) - for i,v in ipairs(t) do - print("table.sort", i, v) - end -end - - -___'' -do - local p, t = tproxy{ "a", "b", "c" } - print("table.unpack", table.unpack(p)) - print("table.unpack", table.unpack(p, 2)) - print("table.unpack", table.unpack(p, 1, 2)) - print("table.unpack", table.unpack(t)) - print("table.unpack", table.unpack(t, 2)) - print("table.unpack", table.unpack(t, 1, 2)) -end - - -___'' -print("math.maxinteger", math.maxinteger+1 > math.maxinteger) -print("math.mininteger", math.mininteger-1 < math.mininteger) - - -___'' -print("math.tointeger", math.tointeger(0)) -print("math.tointeger", math.tointeger(math.pi)) -print("math.tointeger", math.tointeger("123")) -print("math.tointeger", math.tointeger("hello")) -print("math.tointeger", math.tointeger(math.maxinteger+2.0)) -print("math.tointeger", math.tointeger(math.mininteger*2.0)) - - -___'' -print("math.type", math.type(0)) -print("math.type", math.type(math.pi)) -print("math.type", math.type("hello")) - - -___'' -print("math.ult", math.ult(1, 2), math.ult(2, 1)) -print("math.ult", math.ult(-1, 2), math.ult(2, -1)) -print("math.ult", math.ult(-1, -2), math.ult(-2, -1)) -print("math.ult", pcall(math.ult, "x", 2)) -print("math.ult", pcall(math.ult, 1, 2.1)) -___'' - - -if utf8.len then - local unpack = table.unpack or unpack - local function utf8rt(s) - local t = { utf8.codepoint(s, 1, #s) } - local ps, cs = {}, {} - for p,c in utf8.codes(s) do - ps[#ps+1], cs[#cs+1] = p, c - end - print("utf8.codes", unpack(ps)) - print("utf8.codes", unpack(cs)) - print("utf8.codepoint", unpack(t)) - print("utf8.len", utf8.len(s), #t, #s) - print("utf8.char", utf8.char(unpack(t))) - end - utf8rt("äöüßÄÖÜ") - utf8rt("abcdefg") - ___'' - local s = "äöüßÄÖÜ" - print("utf8.offset", utf8.offset(s, 1, 1)) - print("utf8.offset", utf8.offset(s, 2, 1)) - print("utf8.offset", utf8.offset(s, 3, 1)) - print("utf8.offset", pcall(utf8.offset, s, 3, 2)) - print("utf8.offset", utf8.offset(s, 3, 3)) - print("utf8.offset", utf8.offset(s, -1, 7)) - print("utf8.offset", utf8.offset(s, -2, 7)) - print("utf8.offset", utf8.offset(s, -3, 7)) - print("utf8.offset", utf8.offset(s, -1)) - ___'' -else - print("XXX: utf8 module not available") -end - - -if string.pack then - local format = "bBhHlLjJdc3z" - local s = string.pack(format, -128, 255, -32768, 65535, -2147483648, 4294967295, -32768, 65536, 1.25, "abc", "defgh") - print("string.unpack", string.unpack(format, s)) - ___'' -else - print("XXX: string packing not available") -end - - -print("testing Lua API for Lua 5.1 ...") - -___'' -print("debug.getuservalue()", F(debug.getuservalue(false))) -print("debug.setuservalue()", pcall(function() - debug.setuservalue(false, {}) -end)) -print("debug.setmetatable()", F(debug.setmetatable({}, {}))) - - -___'' -do - local t = setmetatable({}, { - __pairs = function() return pairs({ a = "a" }) end, - }) - for k,v in pairs(t) do - print("pairs()", k, v) - end -end - - -___'' -do - local code = "print('hello world')\n" - local badcode = "print('blub\n" - print("load()", pcall(function() load(true) end)) - print("load()", F(load(badcode))) - print("load()", F(load(code))) - print("load()", F(load(code, "[L]"))) - print("load()", F(load(code, "[L]", "b"))) - print("load()", F(load(code, "[L]", "t"))) - print("load()", F(load(code, "[L]", "bt"))) - local f = load(code, "[L]", "bt", {}) - print("load()", pcall(f)) - f = load(code, "[L]", "bt", { print = noprint }) - print("load()", pcall(f)) - local bytecode = string.dump(f) - print("load()", F(load(bytecode))) - print("load()", F(load(bytecode, "[L]"))) - print("load()", F(load(bytecode, "[L]", "b"))) - print("load()", F(load(bytecode, "[L]", "t"))) - print("load()", F(load(bytecode, "[L]", "bt"))) - f = load(bytecode, "[L]", "bt", {}) - print("load()", pcall(f)) - f = load(bytecode, "[L]", "bt", { print = noprint }) - print("load()", pcall(f)) - local function make_loader(code) - local mid = math.floor( #code/2 ) - local array = { code:sub(1, mid), code:sub(mid+1) } - local i = 0 - return function() - i = i + 1 - return array[i] - end - end - print("load()", F(load(make_loader(badcode)))) - print("load()", F(load(make_loader(code)))) - print("load()", F(load(make_loader(code), "[L]"))) - print("load()", F(load(make_loader(code), "[L]", "b"))) - print("load()", F(load(make_loader(code), "[L]", "t"))) - print("load()", F(load(make_loader(code), "[L]", "bt"))) - f = load(make_loader(code), "[L]", "bt", {}) - print("load()", pcall(f)) - f = load(make_loader(code), "[L]", "bt", { print = noprint }) - print("load()", pcall(f)) - print("load()", F(load(make_loader(bytecode)))) - print("load()", F(load(make_loader(bytecode), "[L]"))) - print("load()", F(load(make_loader(bytecode), "[L]", "b"))) - print("load()", F(load(make_loader(bytecode), "[L]", "t"))) - print("load()", F(load(make_loader(bytecode), "[L]", "bt"))) - f = load(make_loader(bytecode), "[L]", "bt", {}) - print("load()", pcall(f)) - f = load(make_loader(bytecode), "[L]", "bt", { print = noprint }) - print("load()", pcall(f)) - writefile("good.lua", code) - writefile("bad.lua", badcode) - writefile("good.luac", bytecode, true) - print("loadfile()", F(loadfile("bad.lua"))) - print("loadfile()", F(loadfile("good.lua"))) - print("loadfile()", F(loadfile("good.lua", "b"))) - print("loadfile()", F(loadfile("good.lua", "t"))) - print("loadfile()", F(loadfile("good.lua", "bt"))) - f = loadfile("good.lua", "bt", {}) - print("loadfile()", pcall(f)) - f = loadfile("good.lua", "bt", { print = noprint }) - print("loadfile()", pcall(f)) - print("loadfile()", F(loadfile("good.luac"))) - print("loadfile()", F(loadfile("good.luac", "b"))) - print("loadfile()", F(loadfile("good.luac", "t"))) - print("loadfile()", F(loadfile("good.luac", "bt"))) - f = loadfile("good.luac", "bt", {}) - print("loadfile()", pcall(f)) - f = loadfile("good.luac", "bt", { print = noprint }) - print("loadfile()", pcall(f)) - os.remove("good.lua") - os.remove("bad.lua") - os.remove("good.luac") -end - - -___'' -do - local function func(throw) - if throw then - error("argh") - else - return 1, 2, 3 - end - end - local function tb(err) return "|"..err.."|" end - print("xpcall()", xpcall(func, debug.traceback, false)) - print("xpcall()", xpcall(func, debug.traceback, true)) - print("xpcall()", xpcall(func, tb, true)) - if mode ~= "module" then - local function func2(cb) - print("xpcall()", xpcall(cb, debug.traceback, "str")) - end - local function func3(cb) - print("pcall()", pcall(cb, "str")) - end - local function cb(arg) - coroutine.yield(2) - return arg - end - local c = coroutine.wrap(func2) - print("xpcall()", c(cb)) - print("xpcall()", c()) - local c = coroutine.wrap(func3) - print("pcall()", c(cb)) - print("pcall()", c()) - end -end - - -___'' -do - local t = setmetatable({ 1 }, { __len = function() return 5 end }) - print("rawlen()", rawlen(t), rawlen("123")) -end - - -___'' -print("os.execute()", os.execute("exit 1")) -io.flush() -print("os.execute()", os.execute("echo 'hello world!'")) -io.flush() -print("os.execute()", os.execute("no_such_file")) - - -___'' -do - local t = table.pack("a", nil, "b", nil) - print("table.(un)pack()", t.n, table.unpack(t, 1, t.n)) -end - - -___'' -do - print("coroutine.running()", F(coroutine.wrap(function() - return coroutine.running() - end)())) - print("coroutine.running()", F(coroutine.running())) - local main_co, co1, co2 = coroutine.running() - -- coroutine.yield - if mode ~= "module" then - print("coroutine.yield()", pcall(function() - coroutine.yield(1, 2, 3) - end)) - end - print("coroutine.yield()", coroutine.wrap(function() - coroutine.yield(1, 2, 3) - end)()) - print("coroutine.resume()", coroutine.resume(main_co, 1, 2, 3)) - co1 = coroutine.create(function(a, b, c) - print("coroutine.resume()", a, b, c) - return a, b, c - end) - print("coroutine.resume()", coroutine.resume(co1, 1, 2, 3)) - co1 = coroutine.create(function() - print("coroutine.status()", "[co1] main is", coroutine.status(main_co)) - print("coroutine.status()", "[co1] co2 is", coroutine.status(co2)) - end) - co2 = coroutine.create(function() - print("coroutine.status()", "[co2] main is", coroutine.status(main_co)) - print("coroutine.status()", "[co2] co2 is", coroutine.status(co2)) - coroutine.yield() - coroutine.resume(co1) - end) - print("coroutine.status()", coroutine.status(main_co)) - print("coroutine.status()", coroutine.status(co2)) - coroutine.resume(co2) - print("coroutine.status()", F(coroutine.status(co2))) - coroutine.resume(co2) - print("coroutine.status()", F(coroutine.status(co2))) -end - - -___'' -print("math.log()", math.log(1000)) -print("math.log()", math.log(1000, 10)) - - -___'' -do - local path, prefix = "./?.lua;?/init.lua;../?.lua", "package.searchpath()" - print(prefix, package.searchpath("no.such.module", path)) - print(prefix, package.searchpath("no.such.module", "")) - print(prefix, package.searchpath("compat53", path)) - print(prefix, package.searchpath("no:such:module", path, ":", "|")) -end - - -___'' -if mode ~= "module" then - local function mod_func() return {} end - local function my_searcher(name) - if name == "my.module" then - print("package.searchers", "my.module found") - return mod_func - end - end - local function my_searcher2(name) - if name == "my.module" then - print("package.searchers", "my.module found 2") - return mod_func - end - end - table.insert(package.searchers, my_searcher) - require("my.module") - package.loaded["my.module"] = nil - local new_s = { my_searcher2 } - for i,f in ipairs(package.searchers) do - new_s[i+1] = f - end - package.searchers = new_s - require("my.module") -end - - -___'' -do - print("string.find()", string.find("abc\0abc\0abc", "[^a\0]+")) - print("string.find()", string.find("abc\0abc\0abc", "%w+\0", 5)) - for x in string.gmatch("abc\0def\0ghi", "[^\0]+") do - print("string.gmatch()", x) - end - for x in string.gmatch("abc\0def\0ghi", "%w*\0") do - print("string.gmatch()", #x) - end - print("string.gsub()", string.gsub("abc\0def\0ghi", "[\0]", "X")) - print("string.gsub()", string.gsub("abc\0def\0ghi", "%w*\0", "X")) - print("string.gsub()", string.gsub("abc\0def\0ghi", "%A", "X")) - print("string.match()", string.match("abc\0abc\0abc", "([^\0a]+)")) - print("string.match()", #string.match("abc\0abc\0abc", ".*\0")) - print("string.rep()", string.rep("a", 0)) - print("string.rep()", string.rep("b", 1)) - print("string.rep()", string.rep("c", 4)) - print("string.rep()", string.rep("a", 0, "|")) - print("string.rep()", string.rep("b", 1, "|")) - print("string.rep()", string.rep("c", 4, "|")) - local _tostring = tostring - function tostring(v) - if type(v) == "number" then - return "(".._tostring(v)..")" - else - return _tostring(v) - end - end - print("string.format()", string.format("%q", "\"\\\0000\0010\002\r\n0\t0\"")) - print("string.format()", string.format("%12.3fx%%sxx%.6s", 3.1, {})) - print("string.format()", string.format("%-3f %%%s %%s", 3.1, true)) - print("string.format()", string.format("% 3.2g %%d %%%s", 3.1, nil)) - print("string.format()", string.format("%+3d %%d %%%%%10.6s", 3, io.stdout)) - print("string.format()", pcall(function() - print("string.format()", string.format("%d %%s", {})) - end)) - tostring = _tostring -end - - -___'' -do - print("io.write()", io.type(io.write("hello world\n"))) - local f = assert(io.tmpfile()) - print("io.tmpfile => file:write()", io.type(f:write("hello world\n"))) - f:close() -end - - -___'' -do - writefile("data.txt", "123 18.8 hello world\ni'm here\n") - io.input("data.txt") - print("io.read()", io.read("*n", "*number", "*l", "*a")) - io.input("data.txt") - print("io.read()", io.read("n", "number", "l", "a")) - io.input(io.stdin) - if not is_puclua51 then - local f = assert(io.open("data.txt", "r")) - print("file:read()", f:read("*n", "*number", "*l", "*a")) - f:close() - f = assert(io.open("data.txt", "r")) - print("file:read()", f:read("n", "number", "l", "a")) - f:close() - os.remove("data.txt") - - local g = assert(io.open("data.txt", "w")) - print("io.open => file:write()", type(g:write("hello"))) - g:close() - end - os.remove("data.txt") -end - - -___'' -do - writefile("data.txt", "123 18.8 hello world\ni'm here\n") - for a,b in io.lines(self, 2, "*l") do - print("io.lines()", a, b) - break - end - for l in io.lines(self) do - print("io.lines()", l) - break - end - for n1,n2,rest in io.lines("data.txt", "*n", "n", "*a") do - print("io.lines()", n1, n2, rest) - end - for l in io.lines("data.txt") do - print("io.lines()", l) - end - print("io.lines()", pcall(function() - for l in io.lines("data.txt", "*x") do print(l) end - end)) - print("io.lines()", pcall(function() - for l in io.lines("no_such_file.txt") do print(l) end - end)) - if mode ~= "module" then - local f = assert(io.open(self, "r")) - print("io.type()", io.type(f)) - for a,b in f:lines(2, "*l") do - print("file:lines()", a, b) - break - end - f:close() - print("io.type()", io.type(f)) - f = assert(io.open("data.txt", "r")) - for n1,n2,rest in f:lines("*n", "n", "*a") do - print("file:lines()", n1, n2, rest) - end - f:close() - f = assert(io.open("data.txt", "r")) - for l in f:lines() do - print("file:lines()", l) - end - f:close() - print("file:lines()", pcall(function() - for l in f:lines() do print(l) end - end)) - print("file:lines()", pcall(function() - local f = assert(io.open("data.txt", "r")) - for l in f:lines("*l", "*x") do print(l) end - f:close() - end)) - end - os.remove("data.txt") - print("io.popen()", pcall(function() - local f = assert(io.popen("echo 'hello' && exit 0", "r")) - print("io.popen()", f:read("*a")) - print("io.popen()", f:close()) - end)) - print("io.popen()", pcall(function() - local f = assert(io.popen("echo 'hello' && exit 5", "r")) - print("io.type()", io.type(f)) - print("io.popen()", f:read("*a")) - print("io.popen()", f:close()) - print("io.type()", io.type(f)) - end)) -end -___'' - - -print("testing C API ...") -local mod = require("testmod") -___'' -print("isinteger", mod.isinteger(1)) -print("isinteger", mod.isinteger(0)) -print("isinteger", mod.isinteger(1234567)) -print("isinteger", mod.isinteger(12.3)) -print("isinteger", mod.isinteger(math.huge)) -print("isinteger", mod.isinteger(math.sqrt(-1))) - -___'' -print("rotate", mod.rotate(1, 1, 2, 3, 4, 5, 6)) -print("rotate", mod.rotate(-1, 1, 2, 3, 4, 5, 6)) -print("rotate", mod.rotate(4, 1, 2, 3, 4, 5, 6)) -print("rotate", mod.rotate(-4, 1, 2, 3, 4, 5, 6)) - -___'' -print("strtonum", mod.strtonum("+123")) -print("strtonum", mod.strtonum(" 123 ")) -print("strtonum", mod.strtonum("-1.23")) -print("strtonum", mod.strtonum(" 123 abc")) -print("strtonum", mod.strtonum("jkl")) - -___'' -local a, b, c = mod.requiref() -print("requiref", type(a), type(b), type(c), - a.boolean, b.boolean, c.boolean, - type(requiref1), type(requiref2), type(requiref3)) - -___'' -local c = coroutine.wrap(function() - mod.extraspace("uvw") - print("getextraspace", mod.extraspace()) - coroutine.yield() - print("getextraspace", mod.extraspace()) - coroutine.yield() - print("getextraspace", mod.extraspace()) -end) -c() -mod.extraspace("abc") -print("getextraspace", mod.extraspace()) -c() -local d = coroutine.wrap(function() - print("getextraspace", mod.extraspace()) - mod.extraspace("xyz") - print("getextraspace", mod.extraspace()) - coroutine.yield() - print("getextraspace", mod.extraspace()) - coroutine.yield() - print("getextraspace", mod.extraspace()) -end) -d() -print("getextraspace", mod.extraspace()) -mod.extraspace("123") -c() -d() - -___'' -local proxy, backend = {}, {} -setmetatable(proxy, { __index = backend, __newindex = backend }) -print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) -print("geti/seti", mod.getseti(proxy, 1)) -print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) -print("geti/seti", mod.getseti(proxy, 1)) -print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) - --- tests for Lua 5.1 -___'' -print("tonumber", mod.tonumber(12)) -print("tonumber", mod.tonumber("12")) -print("tonumber", mod.tonumber("0")) -print("tonumber", mod.tonumber(false)) -print("tonumber", mod.tonumber("error")) - -___'' -print("tointeger", mod.tointeger(12)) -print("tointeger", mod.tointeger(12)) -print("tointeger", mod.tointeger(12.1)) -print("tointeger", mod.tointeger(12.9)) -print("tointeger", mod.tointeger(-12.1)) -print("tointeger", mod.tointeger(-12.9)) -print("tointeger", mod.tointeger("12")) -print("tointeger", mod.tointeger("0")) -print("tointeger", mod.tointeger(math.pi)) -print("tointeger", mod.tointeger(false)) -print("tointeger", mod.tointeger("error")) - -___'' -print("len", mod.len("123")) -print("len", mod.len({ 1, 2, 3})) -print("len", pcall(mod.len, true)) -local ud, meta = mod.newproxy() -meta.__len = function() return 5 end -print("len", mod.len(ud)) -meta.__len = function() return true end -print("len", pcall(mod.len, ud)) - -___'' -print("copy", mod.copy(true, "string", {}, 1)) - -___'' -print("rawgetp/rawsetp", mod.rawxetp()) -print("rawgetp/rawsetp", mod.rawxetp("I'm back")) - -___'' -print("globals", F(mod.globals()), mod.globals() == _G) - -___'' -local t = {} -print("getsubtable", F(mod.subtable(t))) -local x, msg = mod.subtable(t) -print("getsubtable", F(x, msg, x == t.xxx)) - -___'' -print("udata", F(mod.udata())) -print("udata", mod.udata("nosuchtype")) - -___'' -print("uservalue", F(mod.uservalue())) - -___'' -print("upvalues", mod.getupvalues()) - -___'' -print("absindex", mod.absindex("hi", true)) - -___'' -print("arith", mod.arith(2, 1)) -print("arith", mod.arith(3, 5)) - -___'' -print("compare", mod.compare(1, 1)) -print("compare", mod.compare(2, 1)) -print("compare", mod.compare(1, 2)) - -___'' -print("tolstring", mod.tolstring("string")) -local t = setmetatable({}, { - __tostring = function(v) return "mytable" end -}) -print("tolstring", mod.tolstring(t)) -local t = setmetatable({}, { - __tostring = function(v) return nil end -}) -print("tolstring", pcall(mod.tolstring, t)) -local ud, meta = mod.newproxy() -meta.__name = "XXX" -print("tolstring", mod.tolstring(ud):gsub(":.*$", ": yyy")) - -___'' -print("pushstring", mod.pushstring()) - -___'' -print("Buffer", mod.buffer()) - -___'' -print("execresult", mod.exec("exit 0")) -print("execresult", mod.exec("exit 1")) -print("execresult", mod.exec("exit 25")) - -___'' -do - local bin = string.dump(function() end) - local modes = { "t", "b", "bt" } - local codes = { - "", "return true", bin, "invalidsource", "\27invalidbinary" - } - for _,m in ipairs(modes) do - for i,c in ipairs(codes) do - print("loadbufferx", m, i, F(mod.loadstring(c, m))) - end - end - - ___'' - local bom = "\239\187\191" - local shebang = "#!/usr/bin/env lua\n" - codes[#codes+1] = bom .. shebang .. "return true" - codes[#codes+1] = bom .. shebang .. bin - codes[#codes+1] = bom .. shebang .. "invalidsource" - codes[#codes+1] = bom .. shebang .. "\027invalidbinary" - for _,m in ipairs(modes) do - for i,c in ipairs(codes) do - print("loadfilex", m, i, F(mod.loadfile(c, m))) - end - end -end -___'' - diff --git a/lib/compat53/tests/testmod.c b/lib/compat53/tests/testmod.c deleted file mode 100644 index 0d73ed4..0000000 --- a/lib/compat53/tests/testmod.c +++ /dev/null @@ -1,370 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include "compat-5.3.h" - - -static int test_isinteger (lua_State *L) { - lua_pushboolean(L, lua_isinteger(L, 1)); - return 1; -} - - -static int test_rotate (lua_State *L) { - int r = (int)luaL_checkinteger(L, 1); - int n = lua_gettop(L)-1; - luaL_argcheck(L, (r < 0 ? -r : r) <= n, 1, "not enough arguments"); - lua_rotate(L, 2, r); - return n; -} - - -static int test_str2num (lua_State *L) { - const char *s = luaL_checkstring(L, 1); - size_t len = lua_stringtonumber(L, s); - if (len == 0) - lua_pushnumber(L, 0); - lua_pushinteger(L, (lua_Integer)len); - return 2; -} - - -static int my_mod (lua_State *L ) { - lua_newtable(L); - lua_pushboolean(L, 1); - lua_setfield(L, -2, "boolean"); - return 1; -} - -static int test_requiref (lua_State *L) { - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_newtable(L); - lua_pushboolean(L, 0); - lua_setfield(L, -2, "boolean"); - lua_setfield(L, -2, "requiref3"); - lua_pop(L, 1); - luaL_requiref(L, "requiref1", my_mod, 0); - luaL_requiref(L, "requiref2", my_mod, 1); - luaL_requiref(L, "requiref3", my_mod, 1); - return 3; -} - -static int test_getseti (lua_State *L) { - lua_Integer k = luaL_checkinteger(L, 2); - lua_Integer n = 0; - if (lua_geti(L, 1, k) == LUA_TNUMBER) { - n = lua_tointeger(L, -1); - } else { - lua_pop(L, 1); - lua_pushinteger(L, n); - } - lua_pushinteger(L, n+1); - lua_seti(L, 1, k); - return 1; -} - - -#ifndef LUA_EXTRASPACE -#define LUA_EXTRASPACE (sizeof(void*)) -#endif - -static int test_getextraspace (lua_State *L) { - size_t len = 0; - char const* s = luaL_optlstring(L, 1, NULL, &len); - char* p = (char*)lua_getextraspace(L); - lua_pushstring(L, p); - if (s) - memcpy(p, s, len > LUA_EXTRASPACE-1 ? LUA_EXTRASPACE-1 : len+1); - return 1; -} - - -/* additional tests for Lua5.1 */ -#define NUP 3 - -static int test_newproxy (lua_State *L) { - lua_settop(L, 0); - lua_newuserdata(L, 0); - lua_newtable(L); - lua_pushvalue(L, -1); - lua_pushboolean(L, 1); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -3); - return 2; -} - -static int test_absindex (lua_State *L) { - int i = 1; - for (i = 1; i <= NUP; ++i) - lua_pushvalue(L, lua_absindex(L, lua_upvalueindex(i))); - lua_pushvalue(L, lua_absindex(L, LUA_REGISTRYINDEX)); - lua_pushstring(L, lua_typename(L, lua_type(L, lua_absindex(L, -1)))); - lua_replace(L, lua_absindex(L, -2)); - lua_pushvalue(L, lua_absindex(L, -2)); - lua_pushvalue(L, lua_absindex(L, -4)); - lua_pushvalue(L, lua_absindex(L, -6)); - i += 3; - lua_pushvalue(L, lua_absindex(L, 1)); - lua_pushvalue(L, lua_absindex(L, 2)); - lua_pushvalue(L, lua_absindex(L, 3)); - i += 3; - return i; -} - -static int test_arith (lua_State *L) { - lua_settop(L, 2); - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_arith(L, LUA_OPADD); - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_arith(L, LUA_OPSUB); - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_arith(L, LUA_OPMUL); - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_arith(L, LUA_OPDIV); - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_arith(L, LUA_OPMOD); - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_arith(L, LUA_OPPOW); - lua_pushvalue(L, 1); - lua_arith(L, LUA_OPUNM); - return lua_gettop(L)-2; -} - -static int test_compare (lua_State *L) { - luaL_checknumber(L, 1); - luaL_checknumber(L, 2); - lua_settop(L, 2); - lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPEQ)); - lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLT)); - lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLE)); - return 3; -} - -static int test_globals (lua_State *L) { - lua_pushglobaltable(L); - return 1; -} - -static int test_tonumber (lua_State *L) { - int isnum = 0; - lua_Number n = lua_tonumberx(L, 1, &isnum); - if (!isnum) - lua_pushnil(L); - else - lua_pushnumber(L, n); - return 1; -} - -static int test_tointeger (lua_State *L) { - int isnum = 0; - lua_Integer n = lua_tointegerx(L, 1, &isnum); - if (!isnum) - lua_pushnil(L); - else - lua_pushinteger(L, n); - lua_pushinteger(L, lua_tointeger(L, 1)); - return 2; -} - -static int test_len (lua_State *L) { - luaL_checkany(L, 1); - lua_len(L, 1); - lua_pushinteger(L, luaL_len(L, 1)); - return 2; -} - -static int test_copy (lua_State *L) { - int args = lua_gettop(L); - if (args >= 2) { - int i = 0; - for (i = args-1; i > 0; --i) - lua_copy(L, args, i); - } - return args; -} - -/* need an address */ -static char const dummy = 0; - -static int test_rawxetp (lua_State *L) { - if (lua_gettop(L) > 0) - lua_pushvalue(L, 1); - else - lua_pushliteral(L, "hello again"); - lua_rawsetp(L, LUA_REGISTRYINDEX, &dummy); - lua_settop(L, 0); - lua_rawgetp(L, LUA_REGISTRYINDEX, &dummy); - return 1; -} - -static int test_udata (lua_State *L) { - const char *tname = luaL_optstring(L, 1, "utype1"); - void *u1 = lua_newuserdata(L, 1); - int u1pos = lua_gettop(L); - void *u2 = lua_newuserdata(L, 1); - int u2pos = lua_gettop(L); - luaL_newmetatable(L, "utype1"); - luaL_newmetatable(L, "utype2"); - lua_pop(L, 2); - luaL_setmetatable(L, "utype2"); - lua_pushvalue(L, u1pos); - luaL_setmetatable(L, "utype1"); - lua_pop(L, 1); - (void)u1; - (void)u2; - lua_pushlightuserdata(L, luaL_testudata(L, u1pos, tname)); - lua_pushlightuserdata(L, luaL_testudata(L, u2pos, tname)); - luaL_getmetatable(L, "utype1"); - lua_getfield(L, -1, "__name"); - lua_replace(L, -2); - return 3; -} - -static int test_subtable (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 1); - if (luaL_getsubtable(L, 1, "xxx")) { - lua_pushliteral(L, "oldtable"); - } else { - lua_pushliteral(L, "newtable"); - } - return 2; -} - -static int test_uservalue (lua_State *L) { - void *udata = lua_newuserdata(L, 1); - int ui = lua_gettop(L); - lua_newtable(L); - lua_setuservalue(L, ui); - lua_pushinteger(L, lua_getuservalue(L, ui)); - (void)udata; - return 2; -} - -static int test_upvalues (lua_State *L) { - int i = 1; - for (i = 1; i <= NUP; ++i) - lua_pushvalue(L, lua_upvalueindex(i)); - return NUP; -} - -static int test_tolstring (lua_State *L) { - size_t len = 0; - luaL_tolstring(L, 1, &len); - lua_pushinteger(L, (int)len); - return 2; -} - -static int test_pushstring (lua_State *L) { - lua_pushstring(L, lua_pushliteral(L, "abc")); - lua_pushstring(L, lua_pushlstring(L, "abc", 2)); - lua_pushstring(L, lua_pushlstring(L, NULL, 0)); - lua_pushstring(L, lua_pushstring(L, "abc")); - lua_pushboolean(L, NULL == lua_pushstring(L, NULL)); - return 10; -} - -static int test_buffer (lua_State *L) { - luaL_Buffer b; - char *p = luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE+1); - p[0] = 'a'; - p[1] = 'b'; - luaL_addsize(&b, 2); - luaL_addstring(&b, "c"); - lua_pushliteral(L, "d"); - luaL_addvalue(&b); - luaL_addchar(&b, 'e'); - luaL_pushresult(&b); - return 1; -} - -static int test_exec (lua_State *L) { - const char *cmd = luaL_checkstring(L, 1); - errno = 0; - return luaL_execresult(L, system(cmd)); -} - -static int test_loadstring (lua_State *L) { - size_t len = 0; - char const* s = luaL_checklstring(L, 1, &len); - char const* mode = luaL_optstring(L, 2, "bt"); - lua_pushinteger(L, luaL_loadbufferx(L, s, len, s, mode)); - return 2; -} - -static int test_loadfile (lua_State *L) { - char filename[L_tmpnam+1] = { 0 }; - size_t len = 0; - char const* s = luaL_checklstring(L, 1, &len); - char const* mode = luaL_optstring(L, 2, "bt"); - if (tmpnam(filename)) { - FILE* f = fopen(filename, "wb"); - if (f) { - fwrite(s, 1, len, f); - fclose(f); - lua_pushinteger(L, luaL_loadfilex(L, filename, mode)); - remove(filename); - return 2; - } else - remove(filename); - } - return 0; -} - - -static const luaL_Reg funcs[] = { - { "isinteger", test_isinteger }, - { "rotate", test_rotate }, - { "strtonum", test_str2num }, - { "requiref", test_requiref }, - { "getseti", test_getseti }, - { "extraspace", test_getextraspace }, - { "newproxy", test_newproxy }, - { "arith", test_arith }, - { "compare", test_compare }, - { "tonumber", test_tonumber }, - { "tointeger", test_tointeger }, - { "len", test_len }, - { "copy", test_copy }, - { "rawxetp", test_rawxetp }, - { "subtable", test_subtable }, - { "udata", test_udata }, - { "uservalue", test_uservalue }, - { "globals", test_globals }, - { "tolstring", test_tolstring }, - { "pushstring", test_pushstring }, - { "buffer", test_buffer }, - { "exec", test_exec }, - { "loadstring", test_loadstring }, - { "loadfile", test_loadfile }, - { NULL, NULL } -}; - -static const luaL_Reg more_funcs[] = { - { "getupvalues", test_upvalues }, - { "absindex", test_absindex }, - { NULL, NULL } -}; - - -#ifdef __cplusplus -extern "C" { -#endif -int luaopen_testmod (lua_State *L) { - int i = 1; - luaL_newlib(L, funcs); - for (i = 1; i <= NUP; ++i) - lua_pushnumber(L, i); - luaL_setfuncs(L, more_funcs, NUP); - return 1; -} -#ifdef __cplusplus -} -#endif - diff --git a/lib/hashmap/hashmap.c b/lib/hashmap/hashmap.c deleted file mode 100644 index cfc112c..0000000 --- a/lib/hashmap/hashmap.c +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright (c) 2024, Lance Borden -All rights reserved. - -This software is licensed under the BSD 3-Clause License. -You may obtain a copy of the license at: -https://opensource.org/licenses/BSD-3-Clause - -Redistribution and use in source and binary forms, with or without -modification, are permitted under the conditions stated in the BSD 3-Clause -License. - -THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -*/ - -#include "hashmap.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -hashmap_t *hm_new_hashmap() { - hashmap_t *this = malloc(sizeof(hashmap_t)); - this->cap = 8; - this->len = 0; - // null all pointers in list - this->list = calloc((this->cap), sizeof(map_pair_t *)); - return this; -} - -unsigned int hm_hashcode(hashmap_t *this, char *key) { - unsigned int code; - for (code = 0; *key != '\0'; key++) { - code = *key + 31 * code; - } - - return code % (this->cap); -} - -char *hm_get(hashmap_t *this, char *key) { - map_pair_t *current; - for (current = this->list[hm_hashcode(this, key)]; current; - current = current->next) { - if (strcmp(current->key, key) == 0) { - return current->val; - } - } - // the key is not found - return NULL; -} - -void hm_set(hashmap_t *this, char *key, char *val) { - unsigned int idx = hm_hashcode(this, key); - map_pair_t *current; - for (current = this->list[idx]; current; current = current->next) { - if (strcmp(current->key, key) == 0) { - current->val = val; - return; - } - } - - map_pair_t *p = malloc(sizeof(map_pair_t)); - p->key = key; - p->val = val; - p->next = this->list[idx]; - this->list[idx] = p; - this->len++; -} diff --git a/lib/hashmap/hashmap.h b/lib/hashmap/hashmap.h deleted file mode 100644 index d5775c5..0000000 --- a/lib/hashmap/hashmap.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 2024, Lance Borden -All rights reserved. - -This software is licensed under the BSD 3-Clause License. -You may obtain a copy of the license at: -https://opensource.org/licenses/BSD-3-Clause - -Redistribution and use in source and binary forms, with or without -modification, are permitted under the conditions stated in the BSD 3-Clause -License. - -THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -*/ - -#ifndef HASHMAP_H -#define HASHMAP_H - -typedef struct pair { - char *key; - char *val; - struct pair *next; -} map_pair_t; - -typedef struct { - map_pair_t **list; - unsigned int cap; - unsigned int len; -} hashmap_t; - -hashmap_t *hm_new_hashmap(); -unsigned int hm_hashcode(hashmap_t *this, char *key); -char *hm_get(hashmap_t *this, char *key); -void hm_set(hashmap_t *this, char *key, char *val); - -#endif // HASHMAP_H |
