Import some Lua documentation

I personally find it easier to read the documentation in Emacs
using JavaDoc style comments.
This commit is contained in:
Justine Tunney 2021-08-22 15:02:18 -07:00
parent 41b9eb6873
commit 7d25fb0090
16 changed files with 801 additions and 108 deletions

View file

@ -23,14 +23,6 @@
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
static noasan bool __asan_is_valid_strlist(char *const *p) {
for (;; ++p) {
if (!__asan_is_valid(p, sizeof(char *))) return false;
if (!*p) return true;
if (!__asan_is_valid(*p, 1)) return false;
}
}
/**
* Replaces current process with program.
*

View file

@ -402,6 +402,14 @@ bool __asan_is_valid_iov(const struct iovec *iov, int iovlen) {
}
}
bool __asan_is_valid_strlist(char *const *p) {
for (;; ++p) {
if (!__asan_is_valid(p, sizeof(char *))) return false;
if (!*p) return true;
if (!__asan_is_valid(*p, 1)) return false;
}
}
static const char *__asan_dscribe_heap_poison(long c) {
switch (c) {
case kAsanHeapFree:

View file

@ -25,5 +25,6 @@ void __asan_poison(uintptr_t, size_t, int);
void __asan_unpoison(uintptr_t, size_t);
bool __asan_is_valid(const void *, size_t);
bool __asan_is_valid_iov(const struct iovec *, int);
bool __asan_is_valid_strlist(char *const *);
#endif /* COSMOPOLITAN_LIBC_INTRIN_ASAN_H_ */

View file

@ -38,18 +38,18 @@ void *GetZipCdir(const uint8_t *p, size_t n) {
if (READ32LE(p + i) == kZipCdir64LocatorMagic &&
i + kZipCdir64LocatorSize <= n &&
IsZipCdir64(p, n, ZIP_LOCATE64_OFFSET(p + i))) {
return (void *)(p + ZIP_LOCATE64_OFFSET(p + i));
return p + ZIP_LOCATE64_OFFSET(p + i);
} else if (READ32LE(p + i) == kZipCdirHdrMagic && IsZipCdir32(p, n, i)) {
j = i;
do {
if (READ32LE(p + j) == kZipCdir64LocatorMagic &&
j + kZipCdir64LocatorSize <= n &&
IsZipCdir64(p, n, ZIP_LOCATE64_OFFSET(p + j))) {
return (void *)(p + ZIP_LOCATE64_OFFSET(p + j));
return p + ZIP_LOCATE64_OFFSET(p + j);
}
} while (j-- && i - j < 1024);
return (void *)(p + i);
return p + i;
}
} while (i--);
return NULL;
return 0;
}

View file

@ -15,6 +15,7 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "libc/bits/bits.h"
#include "libc/str/highwayhash64.h"
asm(".ident\t\"\\n\\n\
@ -30,14 +31,14 @@ typedef struct {
} HighwayHashState;
static void HighwayHashReset(const uint64_t key[4], HighwayHashState *state) {
state->mul0[0] = 0xdbe6d5d5fe4cce2full;
state->mul0[1] = 0xa4093822299f31d0ull;
state->mul0[2] = 0x13198a2e03707344ull;
state->mul0[3] = 0x243f6a8885a308d3ull;
state->mul1[0] = 0x3bd39e10cb0ef593ull;
state->mul1[1] = 0xc0acf169b5f18a8cull;
state->mul1[2] = 0xbe5466cf34e90c6cull;
state->mul1[3] = 0x452821e638d01377ull;
state->mul0[0] = 0xdbe6d5d5fe4cce2f;
state->mul0[1] = 0xa4093822299f31d0;
state->mul0[2] = 0x13198a2e03707344;
state->mul0[3] = 0x243f6a8885a308d3;
state->mul1[0] = 0x3bd39e10cb0ef593;
state->mul1[1] = 0xc0acf169b5f18a8c;
state->mul1[2] = 0xbe5466cf34e90c6c;
state->mul1[3] = 0x452821e638d01377;
state->v0[0] = state->mul0[0] ^ key[0];
state->v0[1] = state->mul0[1] ^ key[1];
state->v0[2] = state->mul0[2] ^ key[2];
@ -50,14 +51,14 @@ static void HighwayHashReset(const uint64_t key[4], HighwayHashState *state) {
static void ZipperMergeAndAdd(const uint64_t v1, const uint64_t v0,
uint64_t *add1, uint64_t *add0) {
*add0 += (((v0 & 0xff000000ull) | (v1 & 0xff00000000ull)) >> 24) |
(((v0 & 0xff0000000000ull) | (v1 & 0xff000000000000ull)) >> 16) |
(v0 & 0xff0000ull) | ((v0 & 0xff00ull) << 32) |
((v1 & 0xff00000000000000ull) >> 8) | (v0 << 56);
*add1 += (((v1 & 0xff000000ull) | (v0 & 0xff00000000ull)) >> 24) |
(v1 & 0xff0000ull) | ((v1 & 0xff0000000000ull) >> 16) |
((v1 & 0xff00ull) << 24) | ((v0 & 0xff000000000000ull) >> 8) |
((v1 & 0xffull) << 48) | (v0 & 0xff00000000000000ull);
*add0 += (((v0 & 0xff000000) | (v1 & 0xff00000000)) >> 24) |
(((v0 & 0xff0000000000) | (v1 & 0xff000000000000)) >> 16) |
(v0 & 0xff0000) | ((v0 & 0xff00) << 32) |
((v1 & 0xff00000000000000) >> 8) | (v0 << 56);
*add1 += (((v1 & 0xff000000) | (v0 & 0xff00000000)) >> 24) | (v1 & 0xff0000) |
((v1 & 0xff0000000000) >> 16) | ((v1 & 0xff00) << 24) |
((v0 & 0xff000000000000) >> 8) | ((v1 & 0xff) << 48) |
(v0 & 0xff00000000000000);
}
static void Update(const uint64_t lanes[4], HighwayHashState *state) {
@ -74,20 +75,13 @@ static void Update(const uint64_t lanes[4], HighwayHashState *state) {
ZipperMergeAndAdd(state->v0[3], state->v0[2], &state->v1[3], &state->v1[2]);
}
static uint64_t Read64(const uint8_t *src) {
return (uint64_t)src[0] | ((uint64_t)src[1] << 8) | ((uint64_t)src[2] << 16) |
((uint64_t)src[3] << 24) | ((uint64_t)src[4] << 32) |
((uint64_t)src[5] << 40) | ((uint64_t)src[6] << 48) |
((uint64_t)src[7] << 56);
}
static void HighwayHashUpdatePacket(const uint8_t *packet,
HighwayHashState *state) {
uint64_t lanes[4];
lanes[0] = Read64(packet + 0);
lanes[1] = Read64(packet + 8);
lanes[2] = Read64(packet + 16);
lanes[3] = Read64(packet + 24);
lanes[0] = READ64LE(packet + 000);
lanes[1] = READ64LE(packet + 010);
lanes[2] = READ64LE(packet + 020);
lanes[3] = READ64LE(packet + 030);
Update(lanes, state);
}
@ -130,10 +124,10 @@ static void HighwayHashUpdateRemainder(const uint8_t *bytes,
}
static void Permute(const uint64_t v[4], uint64_t *permuted) {
permuted[0] = (v[2] >> 32) | (v[2] << 32);
permuted[1] = (v[3] >> 32) | (v[3] << 32);
permuted[2] = (v[0] >> 32) | (v[0] << 32);
permuted[3] = (v[1] >> 32) | (v[1] << 32);
permuted[0] = v[2] >> 32 | v[2] << 32;
permuted[1] = v[3] >> 32 | v[3] << 32;
permuted[2] = v[0] >> 32 | v[0] << 32;
permuted[3] = v[1] >> 32 | v[1] << 32;
}
static void PermuteAndUpdate(HighwayHashState *state) {

View file

@ -2,10 +2,10 @@
#define COSMOPOLITAN_LIBC_STR_THOMPIKE_H_
#include "libc/nexgen32e/bsr.h"
#define ThomPikeCont(x) (((x)&0300) == 0200)
#define ThomPikeCont(x) (0200 == (0300 & (x)))
#define ThomPikeByte(x) ((x) & (((1 << ThomPikeMsb(x)) - 1) | 3))
#define ThomPikeLen(x) (7 - ThomPikeMsb(x))
#define ThomPikeMsb(x) (((x)&0xff) < 252 ? bsr(~(x)&0xff) : 1)
#define ThomPikeMerge(x, y) ((x) << 6 | (y)&077)
#define ThomPikeMsb(x) ((255 & (x)) < 252 ? bsr(255 & ~(x)) : 1)
#define ThomPikeMerge(x, y) ((x) << 6 | 077 & (y))
#endif /* COSMOPOLITAN_LIBC_STR_THOMPIKE_H_ */

View file

@ -22,8 +22,6 @@
* Converts Windows COBOL timestamp to UNIX epoch in microseconds.
*/
struct timeval WindowsTimeToTimeVal(int64_t x) {
/* return WindowsDurationToTimeVal(x - MODERNITYSECONDS * HECTONANOSECONDS);
*/
return (struct timeval){x / HECTONANOSECONDS - MODERNITYSECONDS,
x % HECTONANOSECONDS / 10};
}

View file

@ -17,9 +17,9 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/alg/alg.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/macros.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/madv.h"
#include "libc/sysv/consts/map.h"
@ -55,7 +55,7 @@ int filecmp(const char *pathname1, const char *pathname2) {
madvise(addr1, size1, MADV_WILLNEED | MADV_SEQUENTIAL);
madvise(addr2, size2, MADV_WILLNEED | MADV_SEQUENTIAL);
errno = olderr;
res = memcmp(addr1, addr2, min(size1, size2));
res = memcmp(addr1, addr2, MIN(size1, size2));
if (!res && size1 != size2) {
char kNul = '\0';
if (size1 > size2) {

View file

@ -29,10 +29,8 @@ TEST(readansi, test) {
ASSERT_NE(-1, pipe(fds));
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
close(fds[0]);
s = "a\eM\e[A→\e[123;456R\e[>c\eOz\xc2\x9bM";
write(fds[1], s, strlen(s));
close(fds[1]);
_exit(0);
}
close(fds[1]);
@ -54,7 +52,6 @@ TEST(readansi, test) {
EXPECT_STREQ("\xc2\x9bM", b);
EXPECT_EQ(0, readansi(fds[0], b, 16));
EXPECT_STREQ("", b);
close(fds[0]);
ASSERT_NE(-1, wait(&ws));
ASSERT_TRUE(WIFEXITED(ws));
ASSERT_EQ(0, WEXITSTATUS(ws));

View file

@ -27,37 +27,37 @@
#define kMaxSize 64
static const uint64_t kTestKey1[4] = {
0x0706050403020100ull,
0x0F0E0D0C0B0A0908ull,
0x1716151413121110ull,
0x1F1E1D1C1B1A1918ull,
0x0706050403020100,
0x0F0E0D0C0B0A0908,
0x1716151413121110,
0x1F1E1D1C1B1A1918,
};
static const uint64_t kTestKey2[4] = {1ull, 2ull, 3ull, 4ull};
static const uint64_t kTestKey2[4] = {1, 2, 3, 4};
const uint64_t kExpected64[kMaxSize + 1] = {
0x907A56DE22C26E53ull, 0x7EAB43AAC7CDDD78ull, 0xB8D0569AB0B53D62ull,
0x5C6BEFAB8A463D80ull, 0xF205A46893007EDAull, 0x2B8A1668E4A94541ull,
0xBD4CCC325BEFCA6Full, 0x4D02AE1738F59482ull, 0xE1205108E55F3171ull,
0x32D2644EC77A1584ull, 0xF6E10ACDB103A90Bull, 0xC3BBF4615B415C15ull,
0x243CC2040063FA9Cull, 0xA89A58CE65E641FFull, 0x24B031A348455A23ull,
0x40793F86A449F33Bull, 0xCFAB3489F97EB832ull, 0x19FE67D2C8C5C0E2ull,
0x04DD90A69C565CC2ull, 0x75D9518E2371C504ull, 0x38AD9B1141D3DD16ull,
0x0264432CCD8A70E0ull, 0xA9DB5A6288683390ull, 0xD7B05492003F028Cull,
0x205F615AEA59E51Eull, 0xEEE0C89621052884ull, 0x1BFC1A93A7284F4Full,
0x512175B5B70DA91Dull, 0xF71F8976A0A2C639ull, 0xAE093FEF1F84E3E7ull,
0x22CA92B01161860Full, 0x9FC7007CCF035A68ull, 0xA0C964D9ECD580FCull,
0x2C90F73CA03181FCull, 0x185CF84E5691EB9Eull, 0x4FC1F5EF2752AA9Bull,
0xF5B7391A5E0A33EBull, 0xB9B84B83B4E96C9Cull, 0x5E42FE712A5CD9B4ull,
0xA150F2F90C3F97DCull, 0x7FA522D75E2D637Dull, 0x181AD0CC0DFFD32Bull,
0x3889ED981E854028ull, 0xFB4297E8C586EE2Dull, 0x6D064A45BB28059Cull,
0x90563609B3EC860Cull, 0x7AA4FCE94097C666ull, 0x1326BAC06B911E08ull,
0xB926168D2B154F34ull, 0x9919848945B1948Dull, 0xA2A98FC534825EBEull,
0xE9809095213EF0B6ull, 0x582E5483707BC0E9ull, 0x086E9414A88A6AF5ull,
0xEE86B98D20F6743Dull, 0xF89B7FF609B1C0A7ull, 0x4C7D9CC19E22C3E8ull,
0x9A97005024562A6Full, 0x5DD41CF423E6EBEFull, 0xDF13609C0468E227ull,
0x6E0DA4F64188155Aull, 0xB755BA4B50D7D4A1ull, 0x887A3484647479BDull,
0xAB8EEBE9BF2139A0ull, 0x75542C5D4CD2A6FFull,
0x907A56DE22C26E53, 0x7EAB43AAC7CDDD78, 0xB8D0569AB0B53D62,
0x5C6BEFAB8A463D80, 0xF205A46893007EDA, 0x2B8A1668E4A94541,
0xBD4CCC325BEFCA6F, 0x4D02AE1738F59482, 0xE1205108E55F3171,
0x32D2644EC77A1584, 0xF6E10ACDB103A90B, 0xC3BBF4615B415C15,
0x243CC2040063FA9C, 0xA89A58CE65E641FF, 0x24B031A348455A23,
0x40793F86A449F33B, 0xCFAB3489F97EB832, 0x19FE67D2C8C5C0E2,
0x04DD90A69C565CC2, 0x75D9518E2371C504, 0x38AD9B1141D3DD16,
0x0264432CCD8A70E0, 0xA9DB5A6288683390, 0xD7B05492003F028C,
0x205F615AEA59E51E, 0xEEE0C89621052884, 0x1BFC1A93A7284F4F,
0x512175B5B70DA91D, 0xF71F8976A0A2C639, 0xAE093FEF1F84E3E7,
0x22CA92B01161860F, 0x9FC7007CCF035A68, 0xA0C964D9ECD580FC,
0x2C90F73CA03181FC, 0x185CF84E5691EB9E, 0x4FC1F5EF2752AA9B,
0xF5B7391A5E0A33EB, 0xB9B84B83B4E96C9C, 0x5E42FE712A5CD9B4,
0xA150F2F90C3F97DC, 0x7FA522D75E2D637D, 0x181AD0CC0DFFD32B,
0x3889ED981E854028, 0xFB4297E8C586EE2D, 0x6D064A45BB28059C,
0x90563609B3EC860C, 0x7AA4FCE94097C666, 0x1326BAC06B911E08,
0xB926168D2B154F34, 0x9919848945B1948D, 0xA2A98FC534825EBE,
0xE9809095213EF0B6, 0x582E5483707BC0E9, 0x086E9414A88A6AF5,
0xEE86B98D20F6743D, 0xF89B7FF609B1C0A7, 0x4C7D9CC19E22C3E8,
0x9A97005024562A6F, 0x5DD41CF423E6EBEF, 0xDF13609C0468E227,
0x6E0DA4F64188155A, 0xB755BA4B50D7D4A1, 0x887A3484647479BD,
0xAB8EEBE9BF2139A0, 0x75542C5D4CD2A6FF,
};
uint32_t KnuthMultiplicativeHash32(const void *buf, size_t size) {

View file

@ -0,0 +1,61 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/mem/mem.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/madv.h"
#include "libc/sysv/consts/o.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
#define N (72 * 1024)
char p[N];
char testlib_enable_tmp_setup_teardown;
TEST(filecmp, testEqual) {
rngset(p, N, rand64, -1);
EXPECT_EQ(0, xbarf("a", p, N));
EXPECT_EQ(0, xbarf("b", p, N));
EXPECT_EQ(0, filecmp("a", "b"));
}
TEST(filecmp, testNotEqual) {
rngset(p, N, rand64, -1);
EXPECT_EQ(0, xbarf("a", p, N));
p[N / 2]++;
EXPECT_EQ(0, xbarf("b", p, N));
EXPECT_NE(0, filecmp("a", "b"));
}
TEST(filecmp, testDifferentLength) {
rngset(p, N, rand64, -1);
EXPECT_EQ(0, xbarf("a", p, N));
EXPECT_EQ(0, xbarf("b", p, N - 1));
EXPECT_NE(0, filecmp("a", "b"));
}
BENCH(filecmp, bench) {
rngset(p, N, rand64, -1);
EXPECT_EQ(0, xbarf("a", p, N));
EXPECT_EQ(0, xbarf("b", p, N));
EZBENCH2("filecmp", donothing, filecmp("a", "b"));
}

View file

@ -31,7 +31,9 @@ TEST_LIBC_X_DIRECTDEPS = \
LIBC_RUNTIME \
LIBC_STDIO \
LIBC_STR \
LIBC_RAND \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_UNICODE \
LIBC_X \

328
third_party/lua/lapi.c vendored
View file

@ -110,7 +110,12 @@ LUA_API int lua_checkstack (lua_State *L, int n) {
return res;
}
/**
* Exchanges values between different threads of the same state.
*
* This funcetion pops n values from the stack from, and pushes them onto
* the stack to.
*/
LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
int i;
if (from == to) return;
@ -126,7 +131,15 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
lua_unlock(to);
}
/**
* lua_atpanic
*
* [-0, +0, ]
*
* lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
*
* Sets a new panic function and returns the old one (see §4.4).
*/
LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
lua_CFunction old;
lua_lock(L);
@ -136,7 +149,15 @@ LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
return old;
}
/**
* lua_version
*
* [-0, +0, ]
*
* lua_Number lua_version (lua_State *L);
*
* Returns the version number of this core.
*/
LUA_API lua_Number lua_version (lua_State *L) {
UNUSED(L);
return LUA_VERSION_NUM;
@ -149,21 +170,51 @@ LUA_API lua_Number lua_version (lua_State *L) {
*/
/*
** convert an acceptable stack index into an absolute index
*/
/**
* lua_absindex
*
* [-0, +0, ]
*
* int lua_absindex (lua_State *L, int idx);
*
* Converts the acceptable index idx into an equivalent absolute index (that
* is, one that does not depend on the stack size).
*/
LUA_API int lua_absindex (lua_State *L, int idx) {
return (idx > 0 || ispseudo(idx))
? idx
: cast_int(L->top - L->ci->func) + idx;
}
/**
* lua_gettop
*
* [-0, +0, ]
*
* int lua_gettop (lua_State *L);
*
* Returns the index of the top element in the stack. Because indices start
* at 1, this result is equal to the number of elements in the stack; in
* particular, 0 means an empty stack.
*/
LUA_API int lua_gettop (lua_State *L) {
return cast_int(L->top - (L->ci->func + 1));
}
/**
* lua_settop
*
* [-?, +?, e]
*
* void lua_settop (lua_State *L, int index);
*
* Accepts any index, or 0, and sets the stack top to this index. If the new
* top is greater than the old one, then the new elements are filled with
* nil. If index is 0, then all stack elements are removed.
*
* This function can run arbitrary code when removing an index marked as
* to-be-closed from the stack.
*/
LUA_API void lua_settop (lua_State *L, int idx) {
CallInfo *ci;
StkId func, newtop;
@ -481,6 +532,11 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
*/
/**
* lua_pushnil [-0, +1, ]
*
* Pushes a nil value onto the stack.
*/
LUA_API void lua_pushnil (lua_State *L) {
lua_lock(L);
setnilvalue(s2v(L->top));
@ -489,6 +545,11 @@ LUA_API void lua_pushnil (lua_State *L) {
}
/**
* lua_pushnumber [-0, +1, ]
*
* Pushes a float with value n onto the stack.
*/
LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
lua_lock(L);
setfltvalue(s2v(L->top), n);
@ -497,6 +558,13 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
}
/**
* lua_pushinteger [-0, +1, ]
*
* void lua_pushinteger (lua_State *L, lua_Integer n);
*
* Pushes an integer with value n onto the stack.
*/
LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
lua_lock(L);
setivalue(s2v(L->top), n);
@ -522,6 +590,17 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
}
/**
* lua_pushstring [-0, +1, m]
*
* Pushes the zero-terminated string pointed to by s onto the stack. Lua will
* make or reuse an internal copy of the given string, so the memory at s can
* be freed or reused immediately after the function returns.
*
* Returns a pointer to the internal copy of the string (see §4.1.3).
*
* If s is NULL, pushes nil and returns NULL.
*/
LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
lua_lock(L);
if (s == NULL)
@ -539,6 +618,12 @@ LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
}
/**
* lua_pushvfstring [-0, +1, v]
*
* Equivalent to lua_pushfstring, except that it receives a va_list instead
* of a variable number of arguments.
*/
LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
va_list argp) {
const char *ret;
@ -550,6 +635,25 @@ LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
}
/**
* lua_pushfstring [-0, +1, v]
*
* Pushes onto the stack a formatted string and returns a pointer to this
* string (see §4.1.3). It is similar to the ISO C function sprintf, but has
* two important differences. First, you do not have to allocate space for
* the result; the result is a Lua string and Lua takes care of memory
* allocation (and deallocation, through garbage collection). Second, the
* conversion specifiers are quite restricted. There are no flags, widths, or
* precisions. The conversion specifiers can only be '%%' (inserts the
* character '%'), '%s' (inserts a zero-terminated string, with no size
* restrictions), '%f' (inserts a lua_Number), '%I' (inserts a lua_Integer),
* '%p' (inserts a pointer), '%d' (inserts an int), '%c' (inserts an int as a
* one-byte character), and '%U' (inserts a long int as a UTF-8 byte
* sequence).
*
* This function may raise errors due to memory overflow or an invalid
* conversion specifier.
*/
LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
const char *ret;
va_list argp;
@ -563,6 +667,32 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
}
/**
* lua_pushcclosure [-n, +1, m]
*
* Pushes a new C closure onto the stack. This function receives a pointer to
* a C function and pushes onto the stack a Lua value of type function that,
* when called, invokes the corresponding C function. The parameter n tells
* how many upvalues this function will have (see §4.2).
*
* Any function to be callable by Lua must follow the correct protocol to
* receive its parameters and return its results (see lua_CFunction).
*
* When a C function is created, it is possible to associate some values with
* it, the so called upvalues; these upvalues are then accessible to the
* function whenever it is called. This association is called a C closure
* (see §4.2). To create a C closure, first the initial values for its
* upvalues must be pushed onto the stack. (When there are multiple upvalues,
* the first value is pushed first.) Then lua_pushcclosure is called to
* create and push the C function onto the stack, with the argument n telling
* how many values will be associated with the function. lua_pushcclosure
* also pops these values from the stack.
*
* The maximum value for n is 255.
*
* When n is zero, this function creates a light C function, which is just a
* pointer to the C function. In that case, it never raises a memory error.
*/
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
lua_lock(L);
if (n == 0) {
@ -589,6 +719,11 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
}
/**
* lua_pushboolean [-0, +1, ]
*
* Pushes a boolean value with value b onto the stack.
*/
LUA_API void lua_pushboolean (lua_State *L, int b) {
lua_lock(L);
if (b)
@ -600,6 +735,16 @@ LUA_API void lua_pushboolean (lua_State *L, int b) {
}
/**
* lua_pushlightuserdata [-0, +1, ]
*
* Pushes a light userdata onto the stack.
*
* Userdata represent C values in Lua. A light userdata represents a pointer,
* a void*. It is a value (like a number): you do not create it, it has no
* individual metatable, and it is not collected (as it was never created). A
* light userdata is equal to "any" light userdata with the same C address.
*/
LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
lua_lock(L);
setpvalue(s2v(L->top), p);
@ -608,6 +753,12 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
}
/**
* lua_pushthread [-0, +1, ]
*
* Pushes the thread represented by L onto the stack. Returns 1 if this
* thread is the main thread of its state.
*/
LUA_API int lua_pushthread (lua_State *L) {
lua_lock(L);
setthvalue(L, s2v(L->top), L);
@ -1220,6 +1371,13 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
*/
/**
* lua_error [-1, +0, v]
*
* Raises a Lua error, using the value on the top of the stack as the error
* object. This function does a long jump, and therefore never returns (see
* luaL_error).
*/
LUA_API int lua_error (lua_State *L) {
TValue *errobj;
lua_lock(L);
@ -1231,10 +1389,39 @@ LUA_API int lua_error (lua_State *L) {
else
luaG_errormsg(L); /* raise a regular error */
/* code unreachable; will unlock when control actually leaves the kernel */
return 0; /* to avoid warnings */
unreachable;
}
/**
* lua_next [-1, +(2|0), v]
*
* Pops a key from the stack, and pushes a keyvalue pair from the table at
* the given index, the "next" pair after the given key. If there are no more
* elements in the table, then lua_next returns 0 and pushes nothing.
*
* A typical table traversal looks like this:
*
* // table is in the stack at index 't'
* lua_pushnil(L); // first key
* while (lua_next(L, t) != 0) {
* // uses 'key' (at index -2) and 'value' (at index -1)
* printf("%s - %s\n",
* lua_typename(L, lua_type(L, -2)),
* lua_typename(L, lua_type(L, -1)));
* // removes 'value'; keeps 'key' for next iteration
* lua_pop(L, 1);
* }
*
* While traversing a table, avoid calling lua_tolstring directly on a key,
* unless you know that the key is actually a string. Recall that
* lua_tolstring may change the value at the given index; this confuses the
* next call to lua_next.
*
* This function may raise an error if the given key is neither nil nor
* present in the table. See function next for the caveats of modifying the
* table during its traversal.
*/
LUA_API int lua_next (lua_State *L, int idx) {
Table *t;
int more;
@ -1252,6 +1439,27 @@ LUA_API int lua_next (lua_State *L, int idx) {
}
/**
* lua_toclose [-0, +0, m]
*
* Marks the given index in the stack as a to-be-closed slot (see §3.3.8).
* Like a to-be-closed variable in Lua, the value at that slot in the stack
* will be closed when it goes out of scope. Here, in the context of a C
* function, to go out of scope means that the running function returns to
* Lua, or there is an error, or the slot is removed from the stack through
* lua_settop or lua_pop, or there is a call to lua_closeslot. A slot marked
* as to-be-closed should not be removed from the stack by any other function
* in the API except lua_settop or lua_pop, unless previously deactivated by
* lua_closeslot.
*
* This function should not be called for an index that is equal to or below
* an active to-be-closed slot.
*
* Note that, both in case of errors and of a regular return, by the time the
* __close metamethod runs, the C stack was already unwound, so that any
* automatic C variable declared in the calling function (e.g., a buffer)
* will be out of scope.
*/
LUA_API void lua_toclose (lua_State *L, int idx) {
int nresults;
StkId o;
@ -1266,7 +1474,15 @@ LUA_API void lua_toclose (lua_State *L, int idx) {
lua_unlock(L);
}
/**
* lua_concat [-n, +1, e]
*
* Concatenates the n values at the top of the stack, pops them, and leaves
* the result on the top. If n is 1, the result is the single value on the
* stack (that is, the function does nothing); if n is 0, the result is the
* empty string. Concatenation is performed following the usual semantics of
* Lua (see §3.4.6).
*/
LUA_API void lua_concat (lua_State *L, int n) {
lua_lock(L);
api_checknelems(L, n);
@ -1281,6 +1497,13 @@ LUA_API void lua_concat (lua_State *L, int n) {
}
/**
* lua_len [-0, +1, e]
*
* Returns the length of the value at the given index. It is equivalent to
* the '#' operator in Lua (see §3.4.7) and may trigger a metamethod for the
* "length" event (see §2.4). The result is pushed on the stack.
*/
LUA_API void lua_len (lua_State *L, int idx) {
TValue *t;
lua_lock(L);
@ -1291,6 +1514,13 @@ LUA_API void lua_len (lua_State *L, int idx) {
}
/**
* lua_getallocf [-0, +0, ]
*
* Returns the memory-allocation function of a given state. If ud is not
* NULL, Lua stores in *ud the opaque pointer given when the memory-allocator
* function was set.
*/
LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
lua_Alloc f;
lua_lock(L);
@ -1301,6 +1531,13 @@ LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
}
/**
* lua_setallocf [-0, +0, ]
*
* void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
*
* Changes the allocator function of a given state to f with user data ud.
*/
LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
lua_lock(L);
G(L)->ud = ud;
@ -1309,6 +1546,13 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
}
/**
* lua_setwarnf [-0, +0, ]
*
* Sets the warning function to be used by Lua to emit warnings (see
* lua_WarnFunction). The ud parameter sets the value ud passed to the
* warning function.
*/
void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) {
lua_lock(L);
G(L)->ud_warn = ud;
@ -1317,6 +1561,14 @@ void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) {
}
/**
* lua_warning [-0, +0, ]
*
* Emits a warning with the given message. A message in a call with tocont
* true should be continued in another call to this function.
*
* See warn for more details about warnings.
*/
void lua_warning (lua_State *L, const char *msg, int tocont) {
lua_lock(L);
luaE_warning(L, msg, tocont);
@ -1325,6 +1577,19 @@ void lua_warning (lua_State *L, const char *msg, int tocont) {
/**
* lua_newuserdatauv [-0, +1, m]
*
* This function creates and pushes on the stack a new full userdata, with
* nuvalue associated Lua values, called user values, plus an associated
* block of raw memory with size bytes. (The user values can be set and read
* with the functions lua_setiuservalue and lua_getiuservalue.)
*
* The function returns the address of the block of memory. Lua ensures that
* this address is valid as long as the corresponding userdata is alive (see
* §2.5). Moreover, if the userdata is marked for finalization (see §2.5.3),
* its address is valid at least until the call to its finalizer.
*/
LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
Udata *u;
lua_lock(L);
@ -1338,7 +1603,6 @@ LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
}
static const char *aux_upvalue (TValue *fi, int n, TValue **val,
GCObject **owner) {
switch (ttypetag(fi)) {
@ -1366,6 +1630,16 @@ static const char *aux_upvalue (TValue *fi, int n, TValue **val,
}
/**
* lua_getupvalue [-0, +(0|1), ]
*
* Gets information about the n-th upvalue of the closure at index funcindex.
* It pushes the upvalue's value onto the stack and returns its name. Returns
* NULL (and pushes nothing) when the index n is greater than the number of
* upvalues.
*
* See debug.getupvalue for more information about upvalues.
*/
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
const char *name;
TValue *val = NULL; /* to avoid warnings */
@ -1380,6 +1654,18 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
}
/**
* lua_setupvalue [-(0|1), +0, ]
*
* Sets the value of a closure's upvalue. It assigns the value on the top of
* the stack to the upvalue and returns its name. It also pops the value from
* the stack.
*
* Returns NULL (and pops nothing) when the index n is greater than the
* number of upvalues.
*
* Parameters funcindex and n are as in the function lua_getupvalue.
*/
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
const char *name;
TValue *val = NULL; /* to avoid warnings */
@ -1413,6 +1699,20 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
}
/**
* lua_upvalueid [-0, +0, ]
*
* Returns a unique identifier for the upvalue numbered n from the closure at
* index funcindex.
*
* These unique identifiers allow a program to check whether different
* closures share upvalues. Lua closures that share an upvalue (that is, that
* access a same external local variable) will return identical ids for those
* upvalue indices.
*
* Parameters funcindex and n are as in the function lua_getupvalue, but n
* cannot be greater than the number of upvalues.
*/
LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
TValue *fi = index2value(L, fidx);
switch (ttypetag(fi)) {
@ -1435,6 +1735,12 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
}
/**
* lua_upvaluejoin [-0, +0, ]
*
* Make the n1-th upvalue of the Lua closure at index funcindex1 refer to the
* n2-th upvalue of the Lua closure at index funcindex2.
*/
LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
int fidx2, int n2) {
LClosure *f1;

View file

@ -15,6 +15,38 @@
/* clang-format off */
/**
* @fileoverview The Auxiliary Library
*
* The auxiliary library provides several convenient functions to interface C
* with Lua. While the basic API provides the primitive functions for all
* interactions between C and Lua, the auxiliary library provides
* higher-level functions for some common tasks.
*
* All functions and types from the auxiliary library are defined in header
* file lauxlib.h and have a prefix luaL_.
*
* All functions in the auxiliary library are built on top of the basic API,
* and so they provide nothing that cannot be done with that API.
* Nevertheless, the use of the auxiliary library ensures more consistency to
* your code.
*
* Several functions in the auxiliary library use internally some extra stack
* slots. When a function in the auxiliary library uses less than five slots,
* it does not check the stack size; it simply assumes that there are enough
* slots.
*
* Several functions in the auxiliary library are used to check C function
* arguments. Because the error message is formatted for arguments (e.g.,
* "bad argument #1"), you should not use these functions for other stack
* values.
*
* Functions called luaL_check* always raise an error if the check is not
* satisfied.
*/
#if !defined(MAX_SIZET)
/* maximum value for size_t */
#define MAX_SIZET ((size_t)(~(size_t)0))
@ -116,6 +148,13 @@ static int lastlevel (lua_State *L) {
}
/**
* luaL_traceback [-0, +1, m]
*
* Creates and pushes a traceback of the stack L1. If msg is not NULL, it is
* appended at the beginning of the traceback. The level parameter tells at
* which level to start the traceback.
*/
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
const char *msg, int level) {
luaL_Buffer b;
@ -160,6 +199,17 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
** =======================================================
*/
/**
* luaL_argerror [-0, +0, v]
*
* Raises an error reporting a problem with argument arg of the C function
* that called it, using a standard message that includes extramsg as a
* comment:
*
* bad argument #arg to 'funcname' (extramsg)
*
* This function never returns.
*/
LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
lua_Debug ar;
if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
@ -177,7 +227,13 @@ LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
arg, ar.name, extramsg);
}
/**
* luaL_typeerror [-0, +0, v]
*
* Raises a type error for the argument arg of the C function that called it,
* using a standard message; tname is a "name" for the expected type. This
* function never returns.
*/
LUALIB_API int luaL_typeerror (lua_State *L, int arg, const char *tname) {
const char *msg;
const char *typearg; /* name for the type of the actual argument */
@ -196,12 +252,18 @@ static void tag_error (lua_State *L, int arg, int tag) {
luaL_typeerror(L, arg, lua_typename(L, tag));
}
/*
** The use of 'lua_pushfstring' ensures this function does not
** need reserved stack space when called.
*/
/**
* luaL_where [-0, +1, m]
*
* Pushes onto the stack a string identifying the current position of the
* control at level lvl in the call stack. Typically this string has the
* following format:
*/
LUALIB_API void luaL_where (lua_State *L, int level) {
/*
** The use of 'lua_pushfstring' ensures this function does not
** need reserved stack space when called.
*/
lua_Debug ar;
if (lua_getstack(L, level, &ar)) { /* check function at level */
lua_getinfo(L, "Sl", &ar); /* get info about it */
@ -213,13 +275,23 @@ LUALIB_API void luaL_where (lua_State *L, int level) {
lua_pushfstring(L, ""); /* else, no information available... */
}
/*
** Again, the use of 'lua_pushvfstring' ensures this function does
** not need reserved stack space when called. (At worst, it generates
** an error with "stack overflow" instead of the given message.)
*/
/**
* luaL_error [-0, +0, v]
*
* Raises an error. The error message format is given by fmt plus any extra
* arguments, following the same rules of lua_pushfstring. It also adds at
* the beginning of the message the file name and the line number where the
* error occurred, if this information is available.
*
* This function never returns, but it is an idiom to use it in C functions
* as return luaL_error(args).
*/
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
/*
** Again, the use of 'lua_pushvfstring' ensures this function does
** not need reserved stack space when called. (At worst, it generates
** an error with "stack overflow" instead of the given message.)
*/
va_list argp;
va_start(argp, fmt);
luaL_where(L, 1);
@ -229,7 +301,12 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
return lua_error(L);
}
/**
* luaL_fileresult [-0, +(1|3), m]
*
* This function produces the return values for file-related functions in the
* standard library (io.open, os.rename, file:seek, etc.).
*/
LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
int en = errno; /* calls to Lua API may change this value */
if (stat) {
@ -268,6 +345,12 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
#endif /* } */
/**
* luaL_execresult [-0, +3, m]
*
* This function produces the return values for process-related functions in
* the standard library (os.execute and io.close).
*/
LUALIB_API int luaL_execresult (lua_State *L, int stat) {
if (stat != 0 && errno != 0) /* error with an 'errno'? */
return luaL_fileresult(L, 0, NULL);
@ -294,6 +377,17 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) {
** =======================================================
*/
/**
* luaL_newmetatable [-0, +1, m]
*
* If the registry already has the key tname, returns 0. Otherwise, creates a
* new table to be used as a metatable for userdata, adds to this new table
* the pair __name = tname, adds to the registry the pair [tname] = new
* table, and returns 1.
*
* In both cases, the function pushes onto the stack the final value
* associated with tname in the registry.
*/
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
@ -306,13 +400,23 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
return 1;
}
/**
* luaL_setmetatable [-0, +0, ]
*
* Sets the metatable of the object on the top of the stack as the metatable
* associated with name tname in the registry (see luaL_newmetatable).
*/
LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
luaL_getmetatable(L, tname);
lua_setmetatable(L, -2);
}
/**
* luaL_testudata [-0, +0, m]
*
* This function works like luaL_checkudata, except that, when the test
* fails, it returns NULL instead of raising an error.
*/
LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
@ -327,7 +431,13 @@ LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
return NULL; /* value is not a userdata with a metatable */
}
/**
* luaL_checkudata [-0, +0, v]
*
* Checks whether the function argument arg is a userdata of the type tname
* (see luaL_newmetatable) and returns the userdata's memory-block address
* (see lua_touserdata).
*/
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
void *p = luaL_testudata(L, ud, tname);
luaL_argexpected(L, p != NULL, ud, tname);
@ -343,6 +453,21 @@ LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
** =======================================================
*/
/**
* luaL_checkoption [-0, +0, v]
*
* Checks whether the function argument arg is a string and searches for this
* string in the array lst (which must be NULL-terminated). Returns the index
* in the array where the string was found. Raises an error if the argument
* is not a string or if the string cannot be found.
*
* If def is not NULL, the function uses def as a default value when there is
* no argument arg or when this argument is nil.
*
* This is a useful function for mapping strings to C enums. (The usual
* convention in Lua libraries is to use strings instead of numbers to select
* options.)
*/
LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
const char *const lst[]) {
const char *name = (def) ? luaL_optstring(L, arg, def) :
@ -373,18 +498,39 @@ LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
}
/**
* luaL_checktype [-0, +0, v]
*
* Checks whether the function argument arg has type t. See lua_type for the
* encoding of types for t.
*/
LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
if (l_unlikely(lua_type(L, arg) != t))
tag_error(L, arg, t);
}
/**
* luaL_checkany [-0, +0, v]
*
* Checks whether the function has an argument of any type (including nil) at
* position arg.
*/
LUALIB_API void luaL_checkany (lua_State *L, int arg) {
if (l_unlikely(lua_type(L, arg) == LUA_TNONE))
luaL_argerror(L, arg, "value expected");
}
/**
* luaL_checklstring [-0, +0, v]
*
* Checks whether the function argument arg is a string and returns this
* string; if l is not NULL fills its referent with the string's length.
*
* This function uses lua_tolstring to get its result, so all conversions and
* caveats of that function apply here.
*/
LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
const char *s = lua_tolstring(L, arg, len);
if (l_unlikely(!s)) tag_error(L, arg, LUA_TSTRING);
@ -392,6 +538,19 @@ LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
}
/**
* luaL_optlstring [-0, +0, v]
*
* If the function argument arg is a string, returns this string. If this
* argument is absent or is nil, returns d. Otherwise, raises an error.
*
* If l is not NULL, fills its referent with the result's length. If the
* result is NULL (only possible when returning d and d == NULL), its length
* is considered zero.
*
* This function uses lua_tolstring to get its result, so all conversions and
* caveats of that function apply here.
*/
LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
const char *def, size_t *len) {
if (lua_isnoneornil(L, arg)) {
@ -403,6 +562,12 @@ LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
}
/**
* luaL_checknumber [-0, +0, v]
*
* Checks whether the function argument arg is a number and returns this
* number converted to a lua_Number.
*/
LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
int isnum;
lua_Number d = lua_tonumberx(L, arg, &isnum);
@ -412,6 +577,13 @@ LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
}
/**
* luaL_optnumber [-0, +0, v]
*
* If the function argument arg is a number, returns this number as a
* lua_Number. If this argument is absent or is nil, returns d. Otherwise,
* raises an error.
*/
LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) {
return luaL_opt(L, luaL_checknumber, arg, def);
}
@ -425,6 +597,12 @@ static void interror (lua_State *L, int arg) {
}
/**
* luaL_checkinteger [-0, +0, v]
*
* Checks whether the function argument arg is an integer (or can be
* converted to an integer) and returns this integer.
*/
LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
int isnum;
lua_Integer d = lua_tointegerx(L, arg, &isnum);
@ -435,6 +613,13 @@ LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
}
/**
* luaL_optinteger [-0, +0, v]
*
* If the function argument arg is an integer (or it is convertible to an
* integer), returns this integer. If this argument is absent or is nil,
* returns d. Otherwise, raises an error.
*/
LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
lua_Integer def) {
return luaL_opt(L, luaL_checkinteger, arg, def);
@ -562,6 +747,12 @@ LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
}
/**
* luaL_addlstring [-?, +?, m]
*
* Adds the string pointed to by s with length l to the buffer B (see
* luaL_Buffer). The string can contain embedded zeros.
*/
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */
char *b = prepbuffsize(B, l, -1);
@ -571,11 +762,23 @@ LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
}
/**
* luaL_addstring [-?, +?, m]
*
* Adds the zero-terminated string pointed to by s to the buffer B (see
* luaL_Buffer).
*/
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
luaL_addlstring(B, s, strlen(s));
}
/**
* luaL_pushresult [-?, +1, m]
*
* Finishes the use of buffer B leaving the final string on the top of the
* stack.
*/
LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
lua_State *L = B->L;
checkbufferlevel(B, -1);
@ -586,6 +789,11 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
}
/**
* luaL_pushresultsize [-?, +1, m]
*
* Equivalent to the sequence luaL_addsize, luaL_pushresult.
*/
LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
luaL_addsize(B, sz);
luaL_pushresult(B);
@ -612,6 +820,12 @@ LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
}
/**
* luaL_buffinit [-0, +0, ]
*
* Initializes a buffer B (see luaL_Buffer). This function does not allocate
* any space; the buffer must be declared as a variable.
*/
LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
B->L = L;
B->b = B->init.b;
@ -621,6 +835,11 @@ LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
}
/**
* luaL_buffinitsize [-?, +?, m]
*
* Equivalent to the sequence luaL_buffinit, luaL_prepbuffsize.
*/
LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
luaL_buffinit(L, B);
return prepbuffsize(B, sz, -1);
@ -671,6 +890,15 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
}
/**
* luaL_unref [-0, +0, ]
*
* Releases the reference ref from the table at index t (see luaL_ref). The
* entry is removed from the table, so that the referred object can be
* collected. The reference ref is also freed to be used again.
*
* If ref is LUA_NOREF or LUA_REFNIL, luaL_unref does nothing.
*/
LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
if (ref >= 0) {
t = lua_absindex(L, t);
@ -759,6 +987,21 @@ static int skipcomment (LoadF *lf, int *cp) {
}
/**
* luaL_loadfilex [-0, +1, m]
*
* Loads a file as a Lua chunk. This function uses lua_load to load the chunk
* in the file named filename. If filename is NULL, then it loads from the
* standard input. The first line in the file is ignored if it starts with a
* #.
*
* The string mode works as in the function lua_load.
*
* This function returns the same results as lua_load or LUA_ERRFILE for
* file-related errors.
*
* As lua_load, this function only loads the chunk; it does not run it.
*/
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
const char *mode) {
LoadF lf;
@ -811,6 +1054,16 @@ static const char *getS (lua_State *L, void *ud, size_t *size) {
}
/**
* luaL_loadbufferx [-0, +1, ]
*
* Loads a buffer as a Lua chunk. This function uses lua_load to load the
* chunk in the buffer pointed to by buff with size sz.
*
* This function returns the same results as lua_load. name is the chunk
* name, used for debug information and error messages. The string mode works
* as in the function lua_load.
*/
LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
const char *name, const char *mode) {
LoadS ls;
@ -820,6 +1073,16 @@ LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
}
/**
* luaL_loadstring [-0, +1, ]
*
* Loads a string as a Lua chunk. This function uses lua_load to load the
* chunk in the zero-terminated string s.
*
* This function returns the same results as lua_load.
*
* Also as lua_load, this function only loads the chunk; it does not run it.
*/
LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
return luaL_loadbuffer(L, s, strlen(s), s);
}
@ -828,6 +1091,14 @@ LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
/**
* luaL_getmetafield [-0, +(0|1), m]
*
* Pushes onto the stack the field e from the metatable of the object at
* index obj and returns the type of the pushed value. If the object does not
* have a metatable, or if the metatable does not have this field, pushes
* nothing and returns LUA_TNIL.
*/
LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
if (!lua_getmetatable(L, obj)) /* no metatable? */
return LUA_TNIL;
@ -844,6 +1115,17 @@ LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
}
/**
* luaL_callmeta [-0, +(0|1), e]
*
* Calls a metamethod.
*
* If the object at index obj has a metatable and this metatable has a field
* e, this function calls this field passing the object as its only argument.
* In this case this function returns true and pushes onto the stack the
* value returned by the call. If there is no metatable or no metamethod,
* this function returns false without pushing any value on the stack.
*/
LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
obj = lua_absindex(L, obj);
if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */
@ -854,6 +1136,14 @@ LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
}
/**
* luaL_len [-0, +0, e]
*
* Returns the "length" of the value at the given index as a number; it is
* equivalent to the '#' operator in Lua (see §3.4.7). Raises an error if the
* result of the operation is not an integer. (This case can only happen
* through metamethods.)
*/
LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
lua_Integer l;
int isnum;
@ -866,6 +1156,18 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
}
/**
* luaL_tolstring [-0, +1, e]
*
* Converts any Lua value at the given index to a C string in a reasonable
* format. The resulting string is pushed onto the stack and also returned by
* the function (see §4.1.3). If len is not NULL, the function also sets *len
* with the string length.
*
* If the value has a metatable with a __tostring field, then luaL_tolstring
* calls the corresponding metamethod with the value as argument, and uses
* the result of the call as its result.
*/
LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
if (!lua_isstring(L, -1))
@ -970,6 +1272,12 @@ LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
}
/**
* luaL_addgsub [-0, +0, m]
*
* Adds a copy of the string s to the buffer B (see luaL_Buffer), replacing
* any occurrence of the string p with the string r.
*/
LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
const char *p, const char *r) {
const char *wild;
@ -983,6 +1291,12 @@ LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
}
/**
* luaL_gsub [-0, +1, m]
*
* Creates a copy of string s, replacing any occurrence of the string p with
* the string r. Pushes the resulting string on the stack and returns it.
*/
LUALIB_API const char *luaL_gsub (lua_State *L, const char *s,
const char *p, const char *r) {
luaL_Buffer b;
@ -1070,6 +1384,16 @@ static void warnfon (void *ud, const char *message, int tocont) {
}
/**
* luaL_newstate [-0, +0, ]
*
* Creates a new Lua state. It calls lua_newstate with an allocator based on
* the standard C allocation functions and then sets a warning function and a
* panic function (see §4.4) that print messages to the standard error
* output.
*
* Returns the new state, or NULL if there is a memory allocation error.
*/
LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL);
if (l_likely(L)) {

View file

@ -275,6 +275,16 @@ static void close_state (lua_State *L) {
}
/**
* lua_newthread [-0, +1, m]
*
* Creates a new thread, pushes it on the stack, and returns a pointer to a
* lua_State that represents this new thread. The new thread returned by this
* function shares with the original thread its global environment, but has
* an independent execution stack.
*
* Threads are subject to garbage collection, like any Lua object.
*/
LUA_API lua_State *lua_newthread (lua_State *L) {
global_State *g;
lua_State *L1;

View file

@ -502,7 +502,7 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
/* extended case mappings */
const Py_UCS4 _PyUnicode_ExtendedCase[] = {
const uint16_t _PyUnicode_ExtendedCase[] = {
181,
956,
924,