From b96b0b5abbf40cbdbed7952bf35a5a27ddf75928 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 16 Aug 2019 14:58:02 -0300 Subject: [PATCH] Added macro 'luaL_pushfail' The macro 'luaL_pushfail' documents all places in the standard libraries that return nil to signal some kind of failure. It is defined as 'lua_pushnil'. The manual also got a notation (@fail) to document those returns. The tests were changed to be agnostic regarding whether 'fail' is 'nil' or 'false'. --- lauxlib.c | 6 +-- lauxlib.h | 4 ++ lbaselib.c | 6 +-- ldblib.c | 14 ++++--- liolib.c | 10 ++--- lmathlib.c | 4 +- loadlib.c | 8 ++-- lstrlib.c | 4 +- lutf8lib.c | 4 +- manual/2html | 1 + manual/manual.of | 87 ++++++++++++++++++++++---------------- testes/api.lua | 2 +- testes/db.lua | 6 +-- testes/errors.lua | 10 ++--- testes/files.lua | 30 ++++++------- testes/literals.lua | 2 +- testes/math.lua | 100 ++++++++++++++++++++++---------------------- testes/pm.lua | 22 +++++----- testes/strings.lua | 6 +-- testes/utf8.lua | 4 +- 20 files changed, 176 insertions(+), 154 deletions(-) diff --git a/lauxlib.c b/lauxlib.c index 014e7052..5a040ac6 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -249,7 +249,7 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { return 1; } else { - lua_pushnil(L); + luaL_pushfail(L); if (fname) lua_pushfstring(L, "%s: %s", fname, strerror(en)); else @@ -291,10 +291,10 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) { if (*what == 'e' && stat == 0) /* successful termination? */ lua_pushboolean(L, 1); else - lua_pushnil(L); + luaL_pushfail(L); lua_pushstring(L, what); lua_pushinteger(L, stat); - return 3; /* return true/nil,what,code */ + return 3; /* return true/fail,what,code */ } } diff --git a/lauxlib.h b/lauxlib.h index f68f6af1..c50cdf4d 100644 --- a/lauxlib.h +++ b/lauxlib.h @@ -153,6 +153,10 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) +/* push the value used to represent failure/error */ +#define luaL_pushfail(L) lua_pushnil(L) + + /* ** {====================================================== ** Generic Buffer manipulation diff --git a/lbaselib.c b/lbaselib.c index c68e6d38..747fd45a 100644 --- a/lbaselib.c +++ b/lbaselib.c @@ -106,7 +106,7 @@ static int luaB_tonumber (lua_State *L) { return 1; } /* else not a number */ } /* else not a number */ - lua_pushnil(L); /* not a number */ + luaL_pushfail(L); /* not a number */ return 1; } @@ -308,9 +308,9 @@ static int load_aux (lua_State *L, int status, int envidx) { return 1; } else { /* error (message is on top of the stack) */ - lua_pushnil(L); + luaL_pushfail(L); lua_insert(L, -2); /* put before error message */ - return 2; /* return nil plus error message */ + return 2; /* return fail plus error message */ } } diff --git a/ldblib.c b/ldblib.c index 64158395..9f7aad51 100644 --- a/ldblib.c +++ b/ldblib.c @@ -65,7 +65,7 @@ static int db_setmetatable (lua_State *L) { static int db_getuservalue (lua_State *L) { int n = (int)luaL_optinteger(L, 2, 1); if (lua_type(L, 1) != LUA_TUSERDATA) - lua_pushnil(L); + luaL_pushfail(L); else if (lua_getiuservalue(L, 1, n) != LUA_TNONE) { lua_pushboolean(L, 1); return 2; @@ -80,7 +80,7 @@ static int db_setuservalue (lua_State *L) { luaL_checkany(L, 2); lua_settop(L, 2); if (!lua_setiuservalue(L, 1, n)) - lua_pushnil(L); + luaL_pushfail(L); return 1; } @@ -159,7 +159,7 @@ static int db_getinfo (lua_State *L) { } else { /* stack level */ if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { - lua_pushnil(L); /* level out of range */ + luaL_pushfail(L); /* level out of range */ return 1; } } @@ -223,7 +223,7 @@ static int db_getlocal (lua_State *L) { return 2; } else { - lua_pushnil(L); /* no name (nor value) */ + luaL_pushfail(L); /* no name (nor value) */ return 1; } } @@ -389,8 +389,10 @@ static int db_gethook (lua_State *L) { char buff[5]; int mask = lua_gethookmask(L1); lua_Hook hook = lua_gethook(L1); - if (hook == NULL) /* no hook? */ - lua_pushnil(L); + if (hook == NULL) { /* no hook? */ + luaL_pushfail(L); + return 1; + } else if (hook != hookf) /* external hook? */ lua_pushliteral(L, "external hook"); else { /* hook table must exist */ diff --git a/liolib.c b/liolib.c index 56507d5e..d8b0a6f9 100644 --- a/liolib.c +++ b/liolib.c @@ -153,7 +153,7 @@ static int io_type (lua_State *L) { luaL_checkany(L, 1); p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); if (p == NULL) - lua_pushnil(L); /* not a file */ + luaL_pushfail(L); /* not a file */ else if (isclosed(p)) lua_pushliteral(L, "closed file"); else @@ -593,7 +593,7 @@ static int g_read (lua_State *L, FILE *f, int first) { return luaL_fileresult(L, 0, NULL); if (!success) { lua_pop(L, 1); /* remove last result */ - lua_pushnil(L); /* push nil instead */ + luaL_pushfail(L); /* push nil instead */ } return n - first; } @@ -624,9 +624,9 @@ static int io_readline (lua_State *L) { 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_isnil(L, -n)) /* read at least one value? */ + if (lua_toboolean(L, -n)) /* read at least one value? */ return n; /* return them */ - else { /* first result is nil: EOF or error */ + else { /* first result is false: 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)); @@ -782,7 +782,7 @@ static void createmeta (lua_State *L) { static int io_noclose (lua_State *L) { LStream *p = tolstream(L); p->closef = &io_noclose; /* keep file opened */ - lua_pushnil(L); + luaL_pushfail(L); lua_pushliteral(L, "cannot close standard file"); return 2; } diff --git a/lmathlib.c b/lmathlib.c index 752647e7..f49eb318 100644 --- a/lmathlib.c +++ b/lmathlib.c @@ -77,7 +77,7 @@ static int math_toint (lua_State *L) { lua_pushinteger(L, n); else { luaL_checkany(L, 1); - lua_pushnil(L); /* value is not convertible to integer */ + luaL_pushfail(L); /* value is not convertible to integer */ } return 1; } @@ -235,7 +235,7 @@ static int math_type (lua_State *L) { lua_pushstring(L, (lua_isinteger(L, 1)) ? "integer" : "float"); else { luaL_checkany(L, 1); - lua_pushnil(L); + luaL_pushfail(L); } return 1; } diff --git a/loadlib.c b/loadlib.c index 9ef00278..d7a3fb23 100644 --- a/loadlib.c +++ b/loadlib.c @@ -408,10 +408,10 @@ static int ll_loadlib (lua_State *L) { if (stat == 0) /* no errors? */ return 1; /* return the loaded function */ else { /* error; error message is on stack top */ - lua_pushnil(L); + luaL_pushfail(L); lua_insert(L, -2); lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); - return 3; /* return nil, error message, and where */ + return 3; /* return fail, error message, and where */ } } @@ -505,9 +505,9 @@ static int ll_searchpath (lua_State *L) { luaL_optstring(L, 4, LUA_DIRSEP)); if (f != NULL) return 1; else { /* error message is on top of the stack */ - lua_pushnil(L); + luaL_pushfail(L); lua_insert(L, -2); - return 2; /* return nil + error message */ + return 2; /* return fail + error message */ } } diff --git a/lstrlib.c b/lstrlib.c index 8c9e1a83..7f4a0184 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -744,7 +744,7 @@ static int str_find_aux (lua_State *L, int find) { const char *p = luaL_checklstring(L, 2, &lp); size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1; if (init > ls) { /* start after string's end? */ - lua_pushnil(L); /* cannot find anything */ + luaL_pushfail(L); /* cannot find anything */ return 1; } /* explicit request or no special characters? */ @@ -779,7 +779,7 @@ static int str_find_aux (lua_State *L, int find) { } } while (s1++ < ms.src_end && !anchor); } - lua_pushnil(L); /* not found */ + luaL_pushfail(L); /* not found */ return 1; } diff --git a/lutf8lib.c b/lutf8lib.c index b4b787e7..e63a5a74 100644 --- a/lutf8lib.c +++ b/lutf8lib.c @@ -103,7 +103,7 @@ static int utflen (lua_State *L) { while (posi <= posj) { const char *s1 = utf8_decode(s + posi, NULL, !lax); if (s1 == NULL) { /* conversion error? */ - lua_pushnil(L); /* return nil ... */ + luaL_pushfail(L); /* return fail ... */ lua_pushinteger(L, posi + 1); /* ... and current position */ return 2; } @@ -216,7 +216,7 @@ static int byteoffset (lua_State *L) { if (n == 0) /* did it find given character? */ lua_pushinteger(L, posi + 1); else /* no such character */ - lua_pushnil(L); + luaL_pushfail(L); return 1; } diff --git a/manual/2html b/manual/2html index 605c6e59..a300f8d4 100755 --- a/manual/2html +++ b/manual/2html @@ -324,6 +324,7 @@ N = function (s) return (string.gsub(s, " ", " ")) end, NE = id, -- tag"foreignphrase", num = id, ["nil"] = fixed(Tag.b"nil"), +fail = fixed(Tag.b"fail"), Open = fixed"{", part = section("h1", true), Pat = compose(verbfixed, prepos("'", "'")), diff --git a/manual/manual.of b/manual/manual.of index bb6ae884..53073a54 100644 --- a/manual/manual.of +++ b/manual/manual.of @@ -4058,12 +4058,15 @@ Returns 0 if the userdata does not have that value. } -@APIEntry{void lua_setmetatable (lua_State *L, int index);| +@APIEntry{int lua_setmetatable (lua_State *L, int index);| @apii{1,0,-} Pops a table from the stack and sets it as the new metatable for the value at the given index. +(For historical reasons, this function returns an @id{int}, +which now is always 1.) + } @APIEntry{void lua_settable (lua_State *L, int index);| @@ -5782,7 +5785,7 @@ that will be called to close the stream when the handle is closed or collected; this function receives the file handle as its sole argument and must return either @true, in case of success, -or @nil plus an error message, in case of error. +or a false value plus an error message, in case of error. Once Lua calls this field, it changes the field value to @id{NULL} to signal that the handle is closed. @@ -5904,6 +5907,14 @@ to its expected parameters. For instance, a function documented as @T{foo(arg)} should not be called without an argument. +The notation @fail means a return value representing +some kind of failure or the absence of a better value to return. +Currently, @fail is equal to @nil, +but that may change in future versions. +The recommendation is to test the success of these functions +with @T{(not status)}, instead of @T{(status == nil)}. + + Currently, Lua has the following standard libraries: @itemize{ @@ -6108,8 +6119,8 @@ with previous results. A return of an empty string, @nil, or no value signals the end of the chunk. If there are no syntactic errors, -returns the compiled chunk as a function; -otherwise, returns @nil plus the error message. +@id{load} returns the compiled chunk as a function; +otherwise, it returns @fail plus the error message. When you load a main chunk, the resulting function will always have exactly one upvalue, @@ -6301,7 +6312,7 @@ When called with no @id{base}, If the argument is already a number or a string convertible to a number, then @id{tonumber} returns this number; -otherwise, it returns @nil. +otherwise, it returns @fail. The conversion of strings can result in integers or floats, according to the lexical conventions of Lua @see{lexical}. @@ -6315,7 +6326,7 @@ In bases @N{above 10}, the letter @Char{A} (in either upper or lower case) @N{represents 10}, @Char{B} @N{represents 11}, and so forth, with @Char{Z} representing 35. If the string @id{e} is not a valid numeral in the given base, -the function returns @nil. +the function returns @fail. } @@ -6762,7 +6773,7 @@ will try to open the files Returns the resulting name of the first file that it can open in read mode (after closing the file), -or @nil plus an error message if none succeeds. +or @fail plus an error message if none succeeds. (This error message lists all file names it tried to open.) } @@ -6841,7 +6852,7 @@ Looks for the first match of @id{pattern} @see{pm} in the string @id{s}. If it finds a match, then @id{find} returns the indices @N{of @T{s}} where this occurrence starts and ends; -otherwise, it returns @nil. +otherwise, it returns @fail. A third, optional numeric argument @id{init} specifies where to start the search; its default value @N{is 1} and can be negative. @@ -7034,7 +7045,7 @@ Looks for the first @emph{match} of the @id{pattern} @see{pm} in the string @id{s}. If it finds one, then @id{match} returns the captures from the pattern; -otherwise it returns @nil. +otherwise it returns @fail. If @id{pattern} specifies no captures, then the whole match is returned. A third, optional numeric argument @id{init} specifies @@ -7499,7 +7510,7 @@ Returns the number of UTF-8 characters in string @id{s} that start between positions @id{i} and @id{j} (both inclusive). The default for @id{i} is @num{1} and for @id{j} is @num{-1}. If it finds any invalid byte sequence, -returns a false value plus the position of the first invalid byte. +returns @fail plus the position of the first invalid byte. } @@ -7515,7 +7526,7 @@ so that @T{utf8.offset(s, -n)} gets the offset of the @id{n}-th character from the end of the string. If the specified character is neither in the subject nor right after its end, -the function returns @nil. +the function returns @fail. As a special case, when @id{n} is 0 the function returns the start of the encoding @@ -7850,7 +7861,7 @@ Returns the tangent of @id{x} (assumed to be in radians). If the value @id{x} is convertible to an integer, returns that integer. -Otherwise, returns @nil. +Otherwise, returns @fail. } @@ -7858,7 +7869,7 @@ Otherwise, returns @nil. Returns @St{integer} if @id{x} is an integer, @St{float} if it is a float, -or @nil if @id{x} is not a number. +or @fail if @id{x} is not a number. } @@ -7897,10 +7908,10 @@ three predefined file handles with their usual meanings from C: The I/O library never closes these files. Unless otherwise stated, -all I/O functions return @nil on failure, +all I/O functions return @fail on failure, plus an error message as a second result and a system-dependent error code as a third result, -and some value different from @nil on success. +and some non-false value on success. On non-POSIX systems, the computation of the error message and error code in case of errors @@ -8021,7 +8032,7 @@ and it is automatically removed when the program ends. Checks whether @id{obj} is a valid file handle. Returns the string @T{"file"} if @id{obj} is an open file handle, @T{"closed file"} if @id{obj} is a closed file handle, -or @nil if @id{obj} is not a file handle. +or @fail if @id{obj} is not a file handle. } @@ -8075,7 +8086,7 @@ Reads the file @id{file}, according to the given formats, which specify what to read. For each format, the function returns a string or a number with the characters read, -or @nil if it cannot read data with the specified format. +or @fail if it cannot read data with the specified format. (In this latter case, the function does not read subsequent formats.) When called without arguments, @@ -8094,31 +8105,32 @@ is a valid prefix for a numeral; if that prefix does not form a valid numeral (e.g., an empty string, @St{0x}, or @St{3.4e-}) or it is too long (more than 200 characters), -it is discarded and the format returns @nil. +it is discarded and the format returns @fail. } @item{@St{a}| reads the whole file, starting at the current position. -On end of file, it returns the empty string. +On end of file, it returns the empty string; +this format never fails. } @item{@St{l}| reads the next line skipping the end of line, -returning @nil on end of file. +returning @fail on end of file. This is the default format. } @item{@St{L}| reads the next line keeping the end-of-line character (if present), -returning @nil on end of file. +returning @fail on end of file. } @item{@emph{number}| reads a string with up to this number of bytes, -returning @nil on end of file. +returning @fail on end of file. If @id{number} is zero, it reads nothing and returns an empty string, -or @nil on end of file. +or @fail on end of file. } } @@ -8139,7 +8151,7 @@ specified by the string @id{whence}, as follows: } In case of success, @id{seek} returns the final file position, measured in bytes from the beginning of the file. -If @id{seek} fails, it returns @nil, +If @id{seek} fails, it returns @fail, plus a string describing the error. The default value for @id{whence} is @T{"cur"}, @@ -8179,7 +8191,6 @@ Writes the value of each of its arguments to @id{file}. The arguments must be strings or numbers. In case of success, this function returns @id{file}. -Otherwise it returns @nil plus a string describing the error. } @@ -8251,7 +8262,7 @@ This function is equivalent to the @ANSI{system}. It passes @id{command} to be executed by an operating system shell. Its first result is @true if the command terminated successfully, -or @nil otherwise. +or @fail otherwise. After this first result the function returns a string plus a number, as follows: @@ -8293,7 +8304,7 @@ closes the Lua state before exiting. @LibEntry{os.getenv (varname)| Returns the value of the process environment variable @id{varname}, -or @nil if the variable is not defined. +or @fail if the variable is not defined. } @@ -8301,7 +8312,7 @@ or @nil if the variable is not defined. Deletes the file (or empty directory, on @x{POSIX} systems) with the given name. -If this function fails, it returns @nil, +If this function fails, it returns @fail plus a string describing the error and the error code. Otherwise, it returns true. @@ -8310,7 +8321,7 @@ Otherwise, it returns true. @LibEntry{os.rename (oldname, newname)| Renames the file or directory named @id{oldname} to @id{newname}. -If this function fails, it returns @nil, +If this function fails, it returns @fail, plus a string describing the error and the error code. Otherwise, it returns true. @@ -8325,7 +8336,7 @@ Sets the current locale of the program. @T{"monetary"}, @T{"numeric"}, or @T{"time"}; the default category is @T{"all"}. The function returns the name of the new locale, -or @nil if the request cannot be honored. +or @fail if the request cannot be honored. If @id{locale} is the empty string, the current locale is set to an implementation-defined native locale. @@ -8444,6 +8455,8 @@ the current hook function, the current hook mask, and the current hook count, as set by the @Lid{debug.sethook} function. +Returns @fail if there is no active hook. + } @LibEntry{debug.getinfo ([thread,] f [, what])| @@ -8458,7 +8471,7 @@ of the given thread: (except for tail calls, which do not count on the stack); and so on. If @id{f} is a number greater than the number of active functions, -then @id{getinfo} returns @nil. +then @id{getinfo} returns @fail. The returned table can contain all the fields returned by @Lid{lua_getinfo}, with the string @id{what} describing which fields to fill in. @@ -8496,7 +8509,8 @@ Compile-time constants may not appear in this listing, if they were optimized away by the compiler. Negative indices refer to vararg arguments; @num{-1} is the first vararg argument. -The function returns @nil if there is no variable with the given index, +The function returns @fail +if there is no variable with the given index, and raises an error when called with a level out of range. (You can call @Lid{debug.getinfo} to check whether the level is valid.) @@ -8527,7 +8541,8 @@ Returns the registry table @see{registry}. This function returns the name and the value of the upvalue with index @id{up} of the function @id{f}. -The function returns @nil if there is no upvalue with the given index. +The function returns @fail +if there is no upvalue with the given index. (For Lua functions, upvalues are the external local variables that the function uses, @@ -8615,7 +8630,7 @@ and @N{level 1} is the hook function.) This function assigns the value @id{value} to the local variable with index @id{local} of the function at level @id{level} of the stack. -The function returns @nil if there is no local +The function returns @fail if there is no local variable with the given index, and raises an error when called with a @id{level} out of range. (You can call @id{getinfo} to check whether the level is valid.) @@ -8638,7 +8653,7 @@ Returns @id{value}. This function assigns the value @id{value} to the upvalue with index @id{up} of the function @id{f}. -The function returns @nil if there is no upvalue +The function returns @fail if there is no upvalue with the given index. Otherwise, it returns the name of the upvalue. @@ -8653,7 +8668,7 @@ the @id{n}-th user value associated to the given @id{udata}. @id{udata} must be a full userdata. Returns @id{udata}, -or @nil if the userdata does not have that value. +or @fail if the userdata does not have that value. } diff --git a/testes/api.lua b/testes/api.lua index 4f9d6717..b2680633 100644 --- a/testes/api.lua +++ b/testes/api.lua @@ -698,7 +698,7 @@ for k, v in ipairs(t) do assert(v1 == v and p) end -assert(debug.getuservalue(4) == nil) +assert(not debug.getuservalue(4)) debug.setuservalue(b, function () return 10 end, 10) collectgarbage() -- function should not be collected diff --git a/testes/db.lua b/testes/db.lua index a64a1130..c43243a6 100644 --- a/testes/db.lua +++ b/testes/db.lua @@ -351,12 +351,12 @@ assert(g(0,0) == 30) debug.sethook(nil); -assert(debug.gethook() == nil) +assert(not debug.gethook()) -- minimal tests for setuservalue/getuservalue do - assert(debug.setuservalue(io.stdin, 10) == nil) + assert(not debug.setuservalue(io.stdin, 10)) local a, b = debug.getuservalue(io.stdin, 10) assert(a == nil and not b) end @@ -414,7 +414,7 @@ end, "c") a:f(1,2,3,4,5) assert(X.self == a and X.a == 1 and X.b == 2 and X.c == nil) assert(XX == 12) -assert(debug.gethook() == nil) +assert(not debug.gethook()) -- testing access to local variables in return hook (bug in 5.2) diff --git a/testes/errors.lua b/testes/errors.lua index 6e7b8004..f9623b1d 100644 --- a/testes/errors.lua +++ b/testes/errors.lua @@ -18,7 +18,7 @@ end local function doit (s) local f, msg = load(s) - if f == nil then return msg end + if not f then return msg end local cond, msg = pcall(f) return (not cond) and msg end @@ -312,8 +312,8 @@ end local function lineerror (s, l) local err,msg = pcall(load(s)) - local line = string.match(msg, ":(%d+):") - assert(tonumber(line) == l) + local line = tonumber(string.match(msg, ":(%d+):")) + assert(line == l or (not line and not l)) end lineerror("local a\n for i=1,'a' do \n print(i) \n end", 2) @@ -359,7 +359,7 @@ local p = [[ g() ]] X=3;lineerror((p), 3) -X=0;lineerror((p), nil) +X=0;lineerror((p), false) X=1;lineerror((p), 2) X=2;lineerror((p), 1) @@ -510,7 +510,7 @@ checksyntax("a\1a = 1", "", "<\\1>", 1) checksyntax("\255a = 1", "", "<\\255>", 1) doit('I = load("a=9+"); a=3') -assert(a==3 and I == nil) +assert(a==3 and not I) print('+') lim = 1000 diff --git a/testes/files.lua b/testes/files.lua index 585e5948..677c0dc2 100644 --- a/testes/files.lua +++ b/testes/files.lua @@ -184,7 +184,7 @@ three local f = assert(io.open(file, "r")) -- second item failing l1, n1, n2, dummy = f:read("l", "n", "n", "l") - assert(l1 == "a line" and n1 == nil) + assert(l1 == "a line" and not n1) end assert(os.remove(file)) @@ -228,7 +228,7 @@ assert(f:read("n") == 0Xdeadbeefdeadbeef); assert(f:read(2) == "x\n") assert(f:read("n") == 0x1.13aP3); assert(f:read(1) == "e") do -- attempt to read too long number - assert(f:read("n") == nil) -- fails + assert(not f:read("n")) -- fails local s = f:read("L") -- read rest of line assert(string.find(s, "^00*\n$")) -- lots of 0's left end @@ -314,13 +314,13 @@ assert(io.read() == "fourth_line") assert(io.read() == "") -- empty line assert(io.read('n') == 3450) assert(io.read(1) == '\n') -assert(io.read(0) == nil) -- end of file -assert(io.read(1) == nil) -- end of file -assert(io.read(30000) == nil) -- end of file +assert(not io.read(0)) -- end of file +assert(not io.read(1)) -- end of file +assert(not io.read(30000)) -- end of file assert(({io.read(1)})[2] == undef) -assert(io.read() == nil) -- end of file +assert(not io.read()) -- end of file assert(({io.read()})[2] == undef) -assert(io.read('n') == nil) -- end of file +assert(not io.read('n')) -- end of file assert(({io.read('n')})[2] == undef) assert(io.read('a') == '') -- end of file (OK for 'a') assert(io.read('a') == '') -- end of file (OK for 'a') @@ -356,7 +356,7 @@ assert(io.read(string.len(t)) == t) assert(io.read(1) == ' ') assert(io.read(0)) assert(io.read('a') == ';end of file\n') -assert(io.read(0) == nil) +assert(not io.read(0)) assert(io.close(io.input())) @@ -364,7 +364,7 @@ assert(io.close(io.input())) do local function ismsg (m) -- error message is not a code number - return (type(m) == "string" and tonumber(m) == nil) + return (type(m) == "string" and not tonumber(m)) end -- read @@ -393,7 +393,7 @@ assert(io.read"L" == "\n") assert(io.read"L" == "\n") assert(io.read"L" == "line\n") assert(io.read"L" == "other") -assert(io.read"L" == nil) +assert(not io.read"L") io.input():close() local f = assert(io.open(file)) @@ -462,7 +462,7 @@ end -- test for multipe arguments in 'lines' io.output(file); io.write"0123456789\n":close() for a,b in io.lines(file, 1, 1) do - if a == "\n" then assert(b == nil) + if a == "\n" then assert(not b) else assert(tonumber(a) == tonumber(b) - 1) end end @@ -473,13 +473,13 @@ end for a,b,c in io.lines(file, "a", 0, 1) do if a == "" then break end - assert(a == "0123456789\n" and b == nil and c == nil) + assert(a == "0123456789\n" and not b and not c) end collectgarbage() -- to close file in previous iteration io.output(file); io.write"00\n10\n20\n30\n40\n":close() for a, b in io.lines(file, "n", "n") do - if a == 40 then assert(b == nil) + if a == 40 then assert(not b) else assert(a == b - 10) end end @@ -654,7 +654,7 @@ and the rest of the file io.input(file) local _,a,b,c,d,e,h,__ = io.read(1, 'n', 'n', 'l', 'l', 'l', 'a', 10) assert(io.close(io.input())) -assert(_ == ' ' and __ == nil) +assert(_ == ' ' and not __) assert(type(a) == 'number' and a==123.4 and b==-56e-2) assert(d=='second line' and e=='third line') assert(h==[[ @@ -706,7 +706,7 @@ if not _soft then io.input():seek('set', 0) y = io.read() -- huge line assert(x == y..'\n'..io.read()) - assert(io.read() == nil) + assert(not io.read()) io.close(io.input()) assert(os.remove(file)) x = nil; y = nil diff --git a/testes/literals.lua b/testes/literals.lua index 27f9377d..e101eabf 100644 --- a/testes/literals.lua +++ b/testes/literals.lua @@ -281,7 +281,7 @@ if os.setlocale("pt_BR") or os.setlocale("ptb") then assert(" 0x.1 " + " 0x,1" + "-0X.1\t" == 0x0.1) - assert(tonumber"inf" == nil and tonumber"NAN" == nil) + assert(not tonumber"inf" and not tonumber"NAN") assert(assert(load(string.format("return %q", 4.51)))() == 4.51) diff --git a/testes/math.lua b/testes/math.lua index bad43901..c7dc8285 100644 --- a/testes/math.lua +++ b/testes/math.lua @@ -39,7 +39,7 @@ do end assert(math.type(0) == "integer" and math.type(0.0) == "float" - and math.type("10") == nil) + and not math.type("10")) local function checkerror (msg, f, ...) @@ -381,17 +381,17 @@ assert(tonumber(1/0) == 1/0) -- 'tonumber' with strings assert(tonumber("0") == 0) -assert(tonumber("") == nil) -assert(tonumber(" ") == nil) -assert(tonumber("-") == nil) -assert(tonumber(" -0x ") == nil) -assert(tonumber{} == nil) +assert(not tonumber("")) +assert(not tonumber(" ")) +assert(not tonumber("-")) +assert(not tonumber(" -0x ")) +assert(not tonumber{}) assert(tonumber'+0.01' == 1/100 and tonumber'+.01' == 0.01 and tonumber'.01' == 0.01 and tonumber'-1.' == -1 and tonumber'+1.' == 1) -assert(tonumber'+ 0.01' == nil and tonumber'+.e1' == nil and - tonumber'1e' == nil and tonumber'1.0e+' == nil and - tonumber'.' == nil) +assert(not tonumber'+ 0.01' and not tonumber'+.e1' and + not tonumber'1e' and not tonumber'1.0e+' and + not tonumber'.') assert(tonumber('-012') == -010-2) assert(tonumber('-1.2e2') == - - -120) @@ -445,45 +445,45 @@ local function f (...) end end -assert(f(tonumber('fFfa', 15)) == nil) -assert(f(tonumber('099', 8)) == nil) -assert(f(tonumber('1\0', 2)) == nil) -assert(f(tonumber('', 8)) == nil) -assert(f(tonumber(' ', 9)) == nil) -assert(f(tonumber(' ', 9)) == nil) -assert(f(tonumber('0xf', 10)) == nil) +assert(not f(tonumber('fFfa', 15))) +assert(not f(tonumber('099', 8))) +assert(not f(tonumber('1\0', 2))) +assert(not f(tonumber('', 8))) +assert(not f(tonumber(' ', 9))) +assert(not f(tonumber(' ', 9))) +assert(not f(tonumber('0xf', 10))) -assert(f(tonumber('inf')) == nil) -assert(f(tonumber(' INF ')) == nil) -assert(f(tonumber('Nan')) == nil) -assert(f(tonumber('nan')) == nil) +assert(not f(tonumber('inf'))) +assert(not f(tonumber(' INF '))) +assert(not f(tonumber('Nan'))) +assert(not f(tonumber('nan'))) -assert(f(tonumber(' ')) == nil) -assert(f(tonumber('')) == nil) -assert(f(tonumber('1 a')) == nil) -assert(f(tonumber('1 a', 2)) == nil) -assert(f(tonumber('1\0')) == nil) -assert(f(tonumber('1 \0')) == nil) -assert(f(tonumber('1\0 ')) == nil) -assert(f(tonumber('e1')) == nil) -assert(f(tonumber('e 1')) == nil) -assert(f(tonumber(' 3.4.5 ')) == nil) +assert(not f(tonumber(' '))) +assert(not f(tonumber(''))) +assert(not f(tonumber('1 a'))) +assert(not f(tonumber('1 a', 2))) +assert(not f(tonumber('1\0'))) +assert(not f(tonumber('1 \0'))) +assert(not f(tonumber('1\0 '))) +assert(not f(tonumber('e1'))) +assert(not f(tonumber('e 1'))) +assert(not f(tonumber(' 3.4.5 '))) -- testing 'tonumber' for invalid hexadecimal formats -assert(tonumber('0x') == nil) -assert(tonumber('x') == nil) -assert(tonumber('x3') == nil) -assert(tonumber('0x3.3.3') == nil) -- two decimal points -assert(tonumber('00x2') == nil) -assert(tonumber('0x 2') == nil) -assert(tonumber('0 x2') == nil) -assert(tonumber('23x') == nil) -assert(tonumber('- 0xaa') == nil) -assert(tonumber('-0xaaP ') == nil) -- no exponent -assert(tonumber('0x0.51p') == nil) -assert(tonumber('0x5p+-2') == nil) +assert(not tonumber('0x')) +assert(not tonumber('x')) +assert(not tonumber('x3')) +assert(not tonumber('0x3.3.3')) -- two decimal points +assert(not tonumber('00x2')) +assert(not tonumber('0x 2')) +assert(not tonumber('0 x2')) +assert(not tonumber('23x')) +assert(not tonumber('- 0xaa')) +assert(not tonumber('-0xaaP ')) -- no exponent +assert(not tonumber('0x0.51p')) +assert(not tonumber('0x5p+-2')) -- testing hexadecimal numerals @@ -705,19 +705,19 @@ do -- testing floor & ceil assert(eqT(math.tointeger(maxint), maxint)) assert(eqT(math.tointeger(maxint .. ""), maxint)) assert(eqT(math.tointeger(minint + 0.0), minint)) - assert(math.tointeger(0.0 - minint) == nil) - assert(math.tointeger(math.pi) == nil) - assert(math.tointeger(-math.pi) == nil) + assert(not math.tointeger(0.0 - minint)) + assert(not math.tointeger(math.pi)) + assert(not math.tointeger(-math.pi)) assert(math.floor(math.huge) == math.huge) assert(math.ceil(math.huge) == math.huge) - assert(math.tointeger(math.huge) == nil) + assert(not math.tointeger(math.huge)) assert(math.floor(-math.huge) == -math.huge) assert(math.ceil(-math.huge) == -math.huge) - assert(math.tointeger(-math.huge) == nil) + assert(not math.tointeger(-math.huge)) assert(math.tointeger("34.0") == 34) - assert(math.tointeger("34.3") == nil) - assert(math.tointeger({}) == nil) - assert(math.tointeger(0/0) == nil) -- NaN + assert(not math.tointeger("34.3")) + assert(not math.tointeger({})) + assert(not math.tointeger(0/0)) -- NaN end diff --git a/testes/pm.lua b/testes/pm.lua index 4d87fad2..94bb63ca 100644 --- a/testes/pm.lua +++ b/testes/pm.lua @@ -28,10 +28,10 @@ a,b = string.find('a\0a\0a\0a\0\0ab', '\0ab', 2); -- finds at the end assert(a == 9 and b == 11); a,b = string.find('a\0a\0a\0a\0\0ab', 'b') -- last position assert(a == 11 and b == 11) -assert(string.find('a\0a\0a\0a\0\0ab', 'b\0') == nil) -- check ending -assert(string.find('', '\0') == nil) +assert(not string.find('a\0a\0a\0a\0\0ab', 'b\0')) -- check ending +assert(not string.find('', '\0')) assert(string.find('alo123alo', '12') == 4) -assert(string.find('alo123alo', '^12') == nil) +assert(not string.find('alo123alo', '^12')) assert(string.match("aaab", ".*b") == "aaab") assert(string.match("aaa", ".*a") == "aaa") @@ -57,17 +57,17 @@ assert(f('aaa', 'ab*a') == 'aa') assert(f('aba', 'ab*a') == 'aba') assert(f('aaab', 'a+') == 'aaa') assert(f('aaa', '^.+$') == 'aaa') -assert(f('aaa', 'b+') == nil) -assert(f('aaa', 'ab+a') == nil) +assert(not f('aaa', 'b+')) +assert(not f('aaa', 'ab+a')) assert(f('aba', 'ab+a') == 'aba') assert(f('a$a', '.$') == 'a') assert(f('a$a', '.%$') == 'a$') assert(f('a$a', '.$.') == 'a$a') -assert(f('a$a', '$$') == nil) -assert(f('a$b', 'a$') == nil) +assert(not f('a$a', '$$')) +assert(not f('a$b', 'a$')) assert(f('a$a', '$') == '') assert(f('', 'b*') == '') -assert(f('aaa', 'bb*') == nil) +assert(not f('aaa', 'bb*')) assert(f('aaab', 'a-') == '') assert(f('aaa', '^.-$') == 'aaa') assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab') @@ -101,7 +101,7 @@ end assert(f1('alo alx 123 b\0o b\0o', '(..*) %1') == "b\0o b\0o") assert(f1('axz123= 4= 4 34', '(.+)=(.*)=%2 %1') == '3= 4= 4 3') assert(f1('=======', '^(=*)=%1$') == '=======') -assert(string.match('==========', '^([=]*)=%1$') == nil) +assert(not string.match('==========', '^([=]*)=%1$')) local function range (i, j) if i <= j then @@ -135,7 +135,7 @@ print('+'); assert(string.match("alo xyzK", "(%w+)K") == "xyz") assert(string.match("254 K", "(%d*)K") == "") assert(string.match("alo ", "(%w*)$") == "") -assert(string.match("alo ", "(%w+)$") == nil) +assert(not string.match("alo ", "(%w+)$")) assert(string.find("(álo)", "%(á") == 1) local a, b, c, d, e = string.match("âlo alo", "^(((.).).* (%w*))$") assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil) @@ -209,7 +209,7 @@ assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4) function isbalanced (s) - return string.find(string.gsub(s, "%b()", ""), "[()]") == nil + return not string.find(string.gsub(s, "%b()", ""), "[()]") end assert(isbalanced("(9 ((8))(\0) 7) \0\0 a b ()(c)() a")) diff --git a/testes/strings.lua b/testes/strings.lua index 2e0e160f..97875ec0 100644 --- a/testes/strings.lua +++ b/testes/strings.lua @@ -56,13 +56,13 @@ a,b = string.find("123456789", "345") assert(string.sub("123456789", a, b) == "345") assert(string.find("1234567890123456789", "345", 3) == 3) assert(string.find("1234567890123456789", "345", 4) == 13) -assert(string.find("1234567890123456789", "346", 4) == nil) +assert(not string.find("1234567890123456789", "346", 4)) assert(string.find("1234567890123456789", ".45", -9) == 13) -assert(string.find("abcdefg", "\0", 5, 1) == nil) +assert(not string.find("abcdefg", "\0", 5, 1)) assert(string.find("", "") == 1) assert(string.find("", "", 1) == 1) assert(not string.find("", "", 2)) -assert(string.find('', 'aaa', 1) == nil) +assert(not string.find('', 'aaa', 1)) assert(('alo(.)alo'):find('(.)', 1, 1) == 4) assert(string.len("") == 0) diff --git a/testes/utf8.lua b/testes/utf8.lua index acbb181d..5954f6e8 100644 --- a/testes/utf8.lua +++ b/testes/utf8.lua @@ -30,8 +30,8 @@ local function checksyntax (s, t) assert(assert(load(ts))() == s) end -assert(utf8.offset("alo", 5) == nil) -assert(utf8.offset("alo", -4) == nil) +assert(not utf8.offset("alo", 5)) +assert(not utf8.offset("alo", -4)) -- 'check' makes several tests over the validity of string 's'. -- 't' is the list of codepoints of 's'.