mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-28 21:40:30 +00:00
Write more redbean unit tests
- Fix DescribeSigset() - Introduce new unix.rmrf() API - Fix redbean sigaction() doc example code - Fix unix.sigaction() w/ more than two args - Improve redbean re module API (non-breaking) - Enhance Lua with Python string multiplication - Make third parameter of unix.socket() default to 0
This commit is contained in:
parent
c5b9902ac9
commit
1c83670229
20 changed files with 738 additions and 204 deletions
2
third_party/lua/README.cosmo
vendored
2
third_party/lua/README.cosmo
vendored
|
@ -34,3 +34,5 @@ LOCAL MODIFICATIONS
|
|||
Added luaL_traceback2() for function parameters in traceback.
|
||||
|
||||
Added Python-like printf modulus operator for strings.
|
||||
|
||||
Added Python-like printf multiply operator for strings.
|
||||
|
|
14
third_party/lua/lstrlib.c
vendored
14
third_party/lua/lstrlib.c
vendored
|
@ -320,12 +320,22 @@ static int arith_sub (lua_State *L) {
|
|||
}
|
||||
|
||||
static int arith_mul (lua_State *L) {
|
||||
return arith(L, LUA_OPMUL, "__mul");
|
||||
if (lua_isinteger(L, 2)) {
|
||||
// [jart] python multiply string operator
|
||||
lua_pushcfunction(L, str_rep);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_call(L, 2, 1);
|
||||
return 1;
|
||||
} else {
|
||||
return arith(L, LUA_OPMUL, "__mul");
|
||||
}
|
||||
}
|
||||
|
||||
static int arith_mod (lua_State *L) {
|
||||
int i, n;
|
||||
if (lua_istable(L, 2)) { // [jart] python printf operator
|
||||
if (lua_istable(L, 2)) {
|
||||
// [jart] python printf operator
|
||||
lua_len(L, 2);
|
||||
n = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
|
26
third_party/lua/lunix.c
vendored
26
third_party/lua/lunix.c
vendored
|
@ -386,6 +386,14 @@ static int LuaUnixMakedirs(lua_State *L) {
|
|||
makedirs(luaL_checkstring(L, 1), luaL_optinteger(L, 2, 0755)));
|
||||
}
|
||||
|
||||
// unix.rmrf(path:str)
|
||||
// ├─→ true
|
||||
// └─→ nil, unix.Errno
|
||||
static int LuaUnixRmrf(lua_State *L) {
|
||||
int olderr = errno;
|
||||
return SysretBool(L, "rmrf", olderr, rmrf(luaL_checkstring(L, 1)));
|
||||
}
|
||||
|
||||
// unix.chdir(path:str)
|
||||
// ├─→ true
|
||||
// └─→ nil, unix.Errno
|
||||
|
@ -1204,10 +1212,9 @@ static int LuaUnixGetsockopt(lua_State *L) {
|
|||
static int LuaUnixSocket(lua_State *L) {
|
||||
int olderr = errno;
|
||||
int family = luaL_optinteger(L, 1, AF_INET);
|
||||
return SysretInteger(
|
||||
L, "socket", olderr,
|
||||
socket(family, luaL_optinteger(L, 2, SOCK_STREAM),
|
||||
luaL_optinteger(L, 3, family == AF_INET ? IPPROTO_TCP : 0)));
|
||||
return SysretInteger(L, "socket", olderr,
|
||||
socket(family, luaL_optinteger(L, 2, SOCK_STREAM),
|
||||
luaL_optinteger(L, 3, 0)));
|
||||
}
|
||||
|
||||
// unix.socketpair([family:int[, type:int[, protocol:int]]])
|
||||
|
@ -1600,11 +1607,17 @@ static int LuaUnixSigaction(lua_State *L) {
|
|||
luaL_argerror(L, 2, "sigaction handler not integer or function");
|
||||
unreachable;
|
||||
}
|
||||
sa.sa_flags = luaL_optinteger(L, 3, 0);
|
||||
if (!lua_isnoneornil(L, 4)) {
|
||||
mask = luaL_checkudata(L, 4, "unix.Sigset");
|
||||
sa.sa_mask.__bits[0] |= mask->__bits[0];
|
||||
sa.sa_mask.__bits[1] |= mask->__bits[1];
|
||||
lua_remove(L, 4);
|
||||
}
|
||||
if (lua_isnoneornil(L, 3)) {
|
||||
sa.sa_flags = 0;
|
||||
} else {
|
||||
sa.sa_flags = lua_tointeger(L, 3);
|
||||
lua_remove(L, 3);
|
||||
}
|
||||
if (!sigaction(sig, saptr, &oldsa)) {
|
||||
lua_getglobal(L, "__signal_handlers");
|
||||
|
@ -2529,7 +2542,6 @@ static const luaL_Reg kLuaUnix[] = {
|
|||
{"getsid", LuaUnixGetsid}, // get session id of pid
|
||||
{"getsockname", LuaUnixGetsockname}, // get address of local end
|
||||
{"getsockopt", LuaUnixGetsockopt}, // get socket tunings
|
||||
{"tiocgwinsz", LuaUnixTiocgwinsz}, // pseudoteletypewriter dimensions
|
||||
{"getuid", LuaUnixGetuid}, // get real user id of process
|
||||
{"gmtime", LuaUnixGmtime}, // destructure unix timestamp
|
||||
{"isatty", LuaUnixIsatty}, // detects pseudoteletypewriters
|
||||
|
@ -2556,6 +2568,7 @@ static const luaL_Reg kLuaUnix[] = {
|
|||
{"recvfrom", LuaUnixRecvfrom}, // receive udp from some address
|
||||
{"rename", LuaUnixRename}, // rename file or directory
|
||||
{"rmdir", LuaUnixRmdir}, // remove empty directory
|
||||
{"rmrf", LuaUnixRmrf}, // remove file recursively
|
||||
{"send", LuaUnixSend}, // send tcp to some address
|
||||
{"sendto", LuaUnixSendto}, // send udp to some address
|
||||
{"setgid", LuaUnixSetgid}, // set real group id of process
|
||||
|
@ -2580,6 +2593,7 @@ static const luaL_Reg kLuaUnix[] = {
|
|||
{"symlink", LuaUnixSymlink}, // create symbolic link
|
||||
{"sync", LuaUnixSync}, // flushes files and disks
|
||||
{"syslog", LuaUnixSyslog}, // logs to system log
|
||||
{"tiocgwinsz", LuaUnixTiocgwinsz}, // pseudoteletypewriter dimensions
|
||||
{"truncate", LuaUnixTruncate}, // shrink or extend file medium
|
||||
{"umask", LuaUnixUmask}, // set default file mask
|
||||
{"unlink", LuaUnixUnlink}, // remove file
|
||||
|
|
76
third_party/regex/regcomp.c
vendored
76
third_party/regex/regcomp.c
vendored
|
@ -2388,12 +2388,15 @@ static reg_errcode_t tre_ast_to_tnfa(tre_ast_node_t *node,
|
|||
* Compiles regular expression, e.g.
|
||||
*
|
||||
* regex_t rx;
|
||||
* EXPECT_EQ(REG_OK, regcomp(&rx, "^[A-Za-z]{2}$", REG_EXTENDED));
|
||||
* EXPECT_EQ(REG_OK, regexec(&rx, "→A", 0, NULL, 0));
|
||||
* CHECK_EQ(REG_OK, regcomp(&rx, "^[A-Za-z]{2}$", REG_EXTENDED));
|
||||
* CHECK_EQ(REG_OK, regexec(&rx, "→A", 0, NULL, 0));
|
||||
* regfree(&rx);
|
||||
*
|
||||
* @param preg points to state, and needs regfree() afterwards
|
||||
* @param regex is utf-8 regular expression string
|
||||
* @param preg points to caller allocated memory that's used to store
|
||||
* your regular expression. This memory needn't be initialized. If
|
||||
* this function succeeds, then `preg` must be passed to regfree()
|
||||
* later on, to free its associated resources
|
||||
* @param regex is utf-8 regular expression nul-terminated string
|
||||
* @param cflags can have REG_EXTENDED, REG_ICASE, REG_NEWLINE, REG_NOSUB
|
||||
* @return REG_OK, REG_NOMATCH, REG_BADPAT, etc.
|
||||
* @see regexec(), regfree(), regerror()
|
||||
|
@ -2579,39 +2582,48 @@ error_exit:
|
|||
|
||||
/**
|
||||
* Frees any memory allocated by regcomp().
|
||||
*
|
||||
* The same object may be destroyed by regfree() multiple times, in
|
||||
* which case subsequent calls do nothing. Once a regex is freed, it may
|
||||
* be passed to regcomp() to reinitialize it.
|
||||
*/
|
||||
void regfree(regex_t *preg) {
|
||||
tre_tnfa_t *tnfa;
|
||||
unsigned int i;
|
||||
tre_tnfa_t *tnfa;
|
||||
tre_tnfa_transition_t *trans;
|
||||
tnfa = (void *)preg->TRE_REGEX_T_FIELD;
|
||||
if (!tnfa) return;
|
||||
for (i = 0; i < tnfa->num_transitions; i++)
|
||||
if (tnfa->transitions[i].state) {
|
||||
if (tnfa->transitions[i].tags)
|
||||
free(tnfa->transitions[i].tags), tnfa->transitions[i].tags = NULL;
|
||||
if (tnfa->transitions[i].neg_classes)
|
||||
free(tnfa->transitions[i].neg_classes),
|
||||
tnfa->transitions[i].neg_classes = NULL;
|
||||
if ((tnfa = preg->TRE_REGEX_T_FIELD)) {
|
||||
preg->TRE_REGEX_T_FIELD = 0;
|
||||
for (i = 0; i < tnfa->num_transitions; i++)
|
||||
if (tnfa->transitions[i].state) {
|
||||
if (tnfa->transitions[i].tags) {
|
||||
free(tnfa->transitions[i].tags);
|
||||
}
|
||||
if (tnfa->transitions[i].neg_classes) {
|
||||
free(tnfa->transitions[i].neg_classes);
|
||||
}
|
||||
}
|
||||
if (tnfa->transitions) {
|
||||
free(tnfa->transitions);
|
||||
}
|
||||
if (tnfa->transitions) free(tnfa->transitions), tnfa->transitions = NULL;
|
||||
if (tnfa->initial) {
|
||||
for (trans = tnfa->initial; trans->state; trans++) {
|
||||
if (trans->tags) free(trans->tags), trans->tags = NULL;
|
||||
if (tnfa->initial) {
|
||||
for (trans = tnfa->initial; trans->state; trans++) {
|
||||
if (trans->tags) {
|
||||
free(trans->tags);
|
||||
}
|
||||
}
|
||||
free(tnfa->initial);
|
||||
}
|
||||
free(tnfa->initial), tnfa->initial = NULL;
|
||||
if (tnfa->submatch_data) {
|
||||
for (i = 0; i < tnfa->num_submatches; i++) {
|
||||
if (tnfa->submatch_data[i].parents) {
|
||||
free(tnfa->submatch_data[i].parents);
|
||||
}
|
||||
}
|
||||
free(tnfa->submatch_data);
|
||||
}
|
||||
if (tnfa->tag_directions) free(tnfa->tag_directions);
|
||||
if (tnfa->firstpos_chars) free(tnfa->firstpos_chars);
|
||||
if (tnfa->minimal_tags) free(tnfa->minimal_tags);
|
||||
free(tnfa);
|
||||
}
|
||||
if (tnfa->submatch_data) {
|
||||
for (i = 0; i < tnfa->num_submatches; i++)
|
||||
if (tnfa->submatch_data[i].parents)
|
||||
free(tnfa->submatch_data[i].parents),
|
||||
tnfa->submatch_data[i].parents = NULL;
|
||||
free(tnfa->submatch_data), tnfa->submatch_data = NULL;
|
||||
}
|
||||
if (tnfa->tag_directions)
|
||||
free(tnfa->tag_directions), tnfa->tag_directions = NULL;
|
||||
if (tnfa->firstpos_chars)
|
||||
free(tnfa->firstpos_chars), tnfa->firstpos_chars = NULL;
|
||||
if (tnfa->minimal_tags) free(tnfa->minimal_tags), tnfa->minimal_tags = NULL;
|
||||
free(tnfa), tnfa = NULL;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue