mirror of
https://github.com/lua/lua
synced 2024-11-22 04:41:23 +03:00
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'.
This commit is contained in:
parent
ca13be9af7
commit
b96b0b5abb
@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
|
14
ldblib.c
14
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 */
|
||||
|
10
liolib.c
10
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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("'", "'")),
|
||||
|
@ -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.
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -184,7 +184,7 @@ three
|
||||
local f <close> = 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
|
||||
|
@ -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)
|
||||
|
||||
|
100
testes/math.lua
100
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
|
||||
|
||||
|
||||
|
@ -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"))
|
||||
|
@ -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)
|
||||
|
@ -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'.
|
||||
|
Loading…
Reference in New Issue
Block a user