diff options
author | Lua Team <team@lua.org> | 2014-10-23 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 2014-10-23 12:00:00 +0000 |
commit | 92fdb95364ed274752b8634c8ba3dca1f1dc5fb3 (patch) | |
tree | d1747f7ed2d0ed06b83ee3073fe4256aefd4a928 | |
parent | d7648e85b78d53a2248de909868192598ad0eb69 (diff) | |
download | lua-github-92fdb95364ed274752b8634c8ba3dca1f1dc5fb3.tar.gz |
Lua 5.3.0-beta5.3.0-beta
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | doc/contents.html | 30 | ||||
-rw-r--r-- | doc/lua.css | 8 | ||||
-rw-r--r-- | doc/manual.html | 732 | ||||
-rw-r--r-- | doc/readme.html | 37 | ||||
-rw-r--r-- | src/Makefile | 6 | ||||
-rw-r--r-- | src/lapi.c | 40 | ||||
-rw-r--r-- | src/lauxlib.c | 53 | ||||
-rw-r--r-- | src/lauxlib.h | 18 | ||||
-rw-r--r-- | src/lbaselib.c | 51 | ||||
-rw-r--r-- | src/lbitlib.c | 26 | ||||
-rw-r--r-- | src/lcorolib.c | 4 | ||||
-rw-r--r-- | src/ldblib.c | 50 | ||||
-rw-r--r-- | src/ldebug.c | 4 | ||||
-rw-r--r-- | src/ldo.c | 17 | ||||
-rw-r--r-- | src/lgc.c | 126 | ||||
-rw-r--r-- | src/liolib.c | 30 | ||||
-rw-r--r-- | src/llex.c | 21 | ||||
-rw-r--r-- | src/lmathlib.c | 14 | ||||
-rw-r--r-- | src/lmem.h | 24 | ||||
-rw-r--r-- | src/loadlib.c | 19 | ||||
-rw-r--r-- | src/lobject.c | 23 | ||||
-rw-r--r-- | src/lobject.h | 6 | ||||
-rw-r--r-- | src/lopcodes.h | 4 | ||||
-rw-r--r-- | src/loslib.c | 9 | ||||
-rw-r--r-- | src/lparser.c | 14 | ||||
-rw-r--r-- | src/lstate.h | 12 | ||||
-rw-r--r-- | src/lstrlib.c | 517 | ||||
-rw-r--r-- | src/ltable.c | 138 | ||||
-rw-r--r-- | src/ltable.h | 9 | ||||
-rw-r--r-- | src/ltablib.c | 68 | ||||
-rw-r--r-- | src/lua.c | 43 | ||||
-rw-r--r-- | src/lua.h | 22 | ||||
-rw-r--r-- | src/luaconf.h | 89 | ||||
-rw-r--r-- | src/lutf8lib.c | 12 | ||||
-rw-r--r-- | src/lvm.c | 10 | ||||
-rw-r--r-- | src/lvm.h | 6 |
37 files changed, 1277 insertions, 1017 deletions
@@ -1,5 +1,5 @@ -This is Lua 5.3.0 (alpha), released on 31 Jul 2014. +This is Lua 5.3.0 (beta), released on 23 Oct 2014. For installation instructions, license details, and further information about Lua, see doc/readme.html. diff --git a/doc/contents.html b/doc/contents.html index b7a00e30..82714f28 100644 --- a/doc/contents.html +++ b/doc/contents.html @@ -22,7 +22,7 @@ Lua 5.3 Reference Manual <P> <IMG SRC="alert.png" ALIGN="absbottom"> -<EM>Some details may change in the final version.</EM> +<EM>A few details may change in the final version.</EM> <P> The reference manual is the official definition of the Lua language. @@ -117,6 +117,7 @@ Freely available under the terms of the <LI><A HREF="manual.html#6.4">6.4 – String Manipulation</A> <UL> <LI><A HREF="manual.html#6.4.1">6.4.1 – Patterns</A> +<LI><A HREF="manual.html#6.4.2">6.4.2 – Format Strings for Pack and Unpack</A> </UL> <LI><A HREF="manual.html#6.5">6.5 – UTF-8 Support</A> <LI><A HREF="manual.html#6.6">6.6 – Table Manipulation</A> @@ -183,7 +184,6 @@ Freely available under the terms of the <P> <A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR> -<A HREF="manual.html#pdf-debug.Csize">debug.Csize</A><BR> <A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR> <A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR> <A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR> @@ -196,6 +196,7 @@ Freely available under the terms of the <A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR> <A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR> <A HREF="manual.html#pdf-debug.setuservalue">debug.setuservalue</A><BR> +<A HREF="manual.html#pdf-debug.sizeof">debug.sizeof</A><BR> <A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR> <A HREF="manual.html#pdf-debug.upvalueid">debug.upvalueid</A><BR> <A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR> @@ -236,6 +237,7 @@ Freely available under the terms of the <A HREF="manual.html#pdf-math.ceil">math.ceil</A><BR> <A HREF="manual.html#pdf-math.cos">math.cos</A><BR> <A HREF="manual.html#pdf-math.deg">math.deg</A><BR> +<A HREF="manual.html#pdf-math.exp">math.exp</A><BR> <A HREF="manual.html#pdf-math.floor">math.floor</A><BR> <A HREF="manual.html#pdf-math.fmod">math.fmod</A><BR> <A HREF="manual.html#pdf-math.huge">math.huge</A><BR> @@ -283,8 +285,6 @@ Freely available under the terms of the <A HREF="manual.html#pdf-string.byte">string.byte</A><BR> <A HREF="manual.html#pdf-string.char">string.char</A><BR> <A HREF="manual.html#pdf-string.dump">string.dump</A><BR> -<A HREF="manual.html#pdf-string.dumpfloat">string.dumpfloat</A><BR> -<A HREF="manual.html#pdf-string.dumpint">string.dumpint</A><BR> <A HREF="manual.html#pdf-string.find">string.find</A><BR> <A HREF="manual.html#pdf-string.format">string.format</A><BR> <A HREF="manual.html#pdf-string.gmatch">string.gmatch</A><BR> @@ -292,17 +292,17 @@ Freely available under the terms of the <A HREF="manual.html#pdf-string.len">string.len</A><BR> <A HREF="manual.html#pdf-string.lower">string.lower</A><BR> <A HREF="manual.html#pdf-string.match">string.match</A><BR> +<A HREF="manual.html#pdf-string.pack">string.pack</A><BR> <A HREF="manual.html#pdf-string.rep">string.rep</A><BR> <A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR> <A HREF="manual.html#pdf-string.sub">string.sub</A><BR> -<A HREF="manual.html#pdf-string.undumpfloat">string.undumpfloat</A><BR> -<A HREF="manual.html#pdf-string.undumpint">string.undumpint</A><BR> +<A HREF="manual.html#pdf-string.unpack">string.unpack</A><BR> <A HREF="manual.html#pdf-string.upper">string.upper</A><BR> <P> <A HREF="manual.html#pdf-table.concat">table.concat</A><BR> -<A HREF="manual.html#pdf-table.copy">table.copy</A><BR> <A HREF="manual.html#pdf-table.insert">table.insert</A><BR> +<A HREF="manual.html#pdf-table.move">table.move</A><BR> <A HREF="manual.html#pdf-table.pack">table.pack</A><BR> <A HREF="manual.html#pdf-table.remove">table.remove</A><BR> <A HREF="manual.html#pdf-table.sort">table.sort</A><BR> @@ -310,7 +310,7 @@ Freely available under the terms of the <P> <A HREF="manual.html#pdf-utf8.char">utf8.char</A><BR> -<A HREF="manual.html#pdf-utf8.charpatt">utf8.charpatt</A><BR> +<A HREF="manual.html#pdf-utf8.charpattern">utf8.charpattern</A><BR> <A HREF="manual.html#pdf-utf8.codepoint">utf8.codepoint</A><BR> <A HREF="manual.html#pdf-utf8.codes">utf8.codes</A><BR> <A HREF="manual.html#pdf-utf8.len">utf8.len</A><BR> @@ -322,10 +322,10 @@ Freely available under the terms of the <P> <A HREF="manual.html#lua_Alloc">lua_Alloc</A><BR> <A HREF="manual.html#lua_CFunction">lua_CFunction</A><BR> -<A HREF="manual.html#lua_Ctx">lua_Ctx</A><BR> <A HREF="manual.html#lua_Debug">lua_Debug</A><BR> <A HREF="manual.html#lua_Hook">lua_Hook</A><BR> <A HREF="manual.html#lua_Integer">lua_Integer</A><BR> +<A HREF="manual.html#lua_KContext">lua_KContext</A><BR> <A HREF="manual.html#lua_KFunction">lua_KFunction</A><BR> <A HREF="manual.html#lua_Number">lua_Number</A><BR> <A HREF="manual.html#lua_Reader">lua_Reader</A><BR> @@ -355,6 +355,7 @@ Freely available under the terms of the <A HREF="manual.html#lua_gethook">lua_gethook</A><BR> <A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR> <A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR> +<A HREF="manual.html#lua_geti">lua_geti</A><BR> <A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR> <A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR> <A HREF="manual.html#lua_getmetatable">lua_getmetatable</A><BR> @@ -421,6 +422,7 @@ Freely available under the terms of the <A HREF="manual.html#lua_setfield">lua_setfield</A><BR> <A HREF="manual.html#lua_setglobal">lua_setglobal</A><BR> <A HREF="manual.html#lua_sethook">lua_sethook</A><BR> +<A HREF="manual.html#lua_seti">lua_seti</A><BR> <A HREF="manual.html#lua_setlocal">lua_setlocal</A><BR> <A HREF="manual.html#lua_setmetatable">lua_setmetatable</A><BR> <A HREF="manual.html#lua_settable">lua_settable</A><BR> @@ -428,7 +430,7 @@ Freely available under the terms of the <A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR> <A HREF="manual.html#lua_setuservalue">lua_setuservalue</A><BR> <A HREF="manual.html#lua_status">lua_status</A><BR> -<A HREF="manual.html#lua_strtonum">lua_strtonum</A><BR> +<A HREF="manual.html#lua_stringtonumber">lua_stringtonumber</A><BR> <A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR> <A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR> <A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR> @@ -470,9 +472,7 @@ Freely available under the terms of the <A HREF="manual.html#luaL_buffinitsize">luaL_buffinitsize</A><BR> <A HREF="manual.html#luaL_callmeta">luaL_callmeta</A><BR> <A HREF="manual.html#luaL_checkany">luaL_checkany</A><BR> -<A HREF="manual.html#luaL_checkint">luaL_checkint</A><BR> <A HREF="manual.html#luaL_checkinteger">luaL_checkinteger</A><BR> -<A HREF="manual.html#luaL_checklong">luaL_checklong</A><BR> <A HREF="manual.html#luaL_checklstring">luaL_checklstring</A><BR> <A HREF="manual.html#luaL_checknumber">luaL_checknumber</A><BR> <A HREF="manual.html#luaL_checkoption">luaL_checkoption</A><BR> @@ -501,9 +501,7 @@ Freely available under the terms of the <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> <A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR> -<A HREF="manual.html#luaL_optint">luaL_optint</A><BR> <A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR> -<A HREF="manual.html#luaL_optlong">luaL_optlong</A><BR> <A HREF="manual.html#luaL_optlstring">luaL_optlstring</A><BR> <A HREF="manual.html#luaL_optnumber">luaL_optnumber</A><BR> <A HREF="manual.html#luaL_optstring">luaL_optstring</A><BR> @@ -529,10 +527,10 @@ Freely available under the terms of the <HR> <SMALL CLASS="footer"> Last update: -Thu Jul 31 14:04:18 BRT 2014 +Wed Oct 22 21:16:56 BRST 2014 </SMALL> <!-- -Last change: updated for Lua 5.3.0 (alpha) +Last change: updated for Lua 5.3.0 (beta) --> </BODY> diff --git a/doc/lua.css b/doc/lua.css index 98f0fcda..3199a2b6 100644 --- a/doc/lua.css +++ b/doc/lua.css @@ -53,6 +53,7 @@ a:visited { a:link:hover, a:visited:hover { color: #000080 ; background-color: #D0D0FF ; + border-radius: 4px; } a:link:active, a:visited:active { @@ -90,10 +91,15 @@ table hr { input[type=text] { border: solid #a0a0a0 2px ; border-radius: 2em ; - -moz-border-radius: 2em ; background-image: url('images/search.png') ; background-repeat: no-repeat ; background-position: 4px center ; padding-left: 20px ; height: 2em ; } + +pre.session { + background-color: #F8F8F8 ; + padding: 1em ; + border-radius: 8px ; +} diff --git a/doc/manual.html b/doc/manual.html index 186597b5..70773501 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -18,7 +18,7 @@ Lua 5.3 Reference Manual <P> <IMG SRC="alert.png" ALIGN="absbottom"> -<EM>Some details may change in the final version.</EM> +<EM>A few details may change in the final version.</EM> <P> by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes @@ -38,7 +38,7 @@ Freely available under the terms of the <!-- ====================================================================== --> <p> -<!-- $Id: manual.of,v 1.125 2014/07/31 13:58:08 roberto Exp $ --> +<!-- $Id: manual.of,v 1.136 2014/10/22 16:16:43 roberto Exp $ --> @@ -49,7 +49,7 @@ Freely available under the terms of the Lua is an extension programming language designed to support general procedural programming with data description facilities. -It also offers good support for object-oriented programming, +Lua also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, lightweight, embeddable scripting language for any program that needs one. @@ -58,7 +58,7 @@ the common subset of Standard C and C++. <p> -Being an extension language, Lua has no notion of a "main" program: +As an extension language, Lua has no notion of a "main" program: it only works <em>embedded</em> in a host client, called the <em>embedding program</em> or simply the <em>host</em>. The host program can invoke functions to execute a piece of Lua code, @@ -131,6 +131,8 @@ integer numbers and real (floating-point) numbers. Lua is 8-bit clean: strings can contain any 8-bit value, including embedded zeros ('<code>\0</code>'). +Lua is also enconding-agnostic; +it makes no assumptions about the contents of a string. <p> @@ -139,21 +141,21 @@ one called <em>integer</em> and the other called <em>float</em>. Lua has explicit rules about when each representation is used, but it also converts between them automatically as needed (see <a href="#3.4.3">§3.4.3</a>). Therefore, -the programmer has the option of mostly ignoring the difference +the programmer may choose to mostly ignore the difference between integers and floats -or assuming complete control over the representation of each value. +or to assume complete control over the representation of each number. Standard Lua uses 64-bit integers and double-precision (64-bit) floats, but you can also compile Lua so that it uses 32-bit integers and/or single-precision (32-bit) floats. -The option with 32 bits both for integers and floats +The option with 32 bits for both integers and floats (called <em>Small Lua</em>) is particularly attractive -for small machines. +for small machines and embedded systems. <p> Lua can call (and manipulate) functions written in Lua and -functions written in C -(see <a href="#3.4.10">§3.4.10</a>). +functions written in C (see <a href="#3.4.10">§3.4.10</a>). +Both are represented by the type <em>function</em>. <p> @@ -161,8 +163,10 @@ The type <em>userdata</em> is provided to allow arbitrary C data to be stored in Lua variables. A userdata value represents a block of raw memory. There are two kinds of userdata: -full userdata, where the block of memory is managed by Lua, -and light userdata, where the block of memory is managed by the host. +<em>full userdata</em>, +which is an object with a block of memory managed by Lua, +and <em>light userdata</em>, +which is simply a C pointer value. Userdata has no predefined operations in Lua, except assignment and identity test. By using <em>metatables</em>, @@ -176,7 +180,7 @@ This guarantees the integrity of data owned by the host program. <p> The type <em>thread</em> represents independent threads of execution and it is used to implement coroutines (see <a href="#2.6">§2.6</a>). -Do not confuse Lua threads with operating-system threads. +Lua threads are not related to operating-system threads. Lua supports coroutines on all systems, even those that do not support threads natively. @@ -184,9 +188,9 @@ even those that do not support threads natively. <p> The type <em>table</em> implements associative arrays, that is, arrays that can be indexed not only with numbers, -but with any Lua value except <b>nil</b> and NaN -(<em>Not a Number</em>, a special numeric value used to represent -undefined or unrepresentable results, such as <code>0/0</code>). +but with any Lua value except <b>nil</b> and NaN. +(<em>Not a Number</em> is a special numeric value used to represent +undefined or unrepresentable results, such as <code>0/0</code>.) Tables can be <em>heterogeneous</em>; that is, they can contain values of all types (except <b>nil</b>). Any key with value <b>nil</b> is not considered part of the table. @@ -195,7 +199,7 @@ an associated value <b>nil</b>. <p> -Tables are the sole data structuring mechanism in Lua; +Tables are the sole data-structuring mechanism in Lua; they can be used to represent ordinary arrays, sequences, symbol tables, sets, records, graphs, trees, etc. To represent records, Lua uses the field name as an index. @@ -207,8 +211,8 @@ There are several convenient ways to create tables in Lua <p> We use the term <em>sequence</em> to denote a table where -the set of all positive numeric keys is equal to <em>{1..n}</em> -for some integer <em>n</em>, +the set of all positive numeric keys is equal to {1..<em>n</em>} +for some non-negative integer <em>n</em>, which is called the length of the sequence (see <a href="#3.4.7">§3.4.7</a>). @@ -228,9 +232,6 @@ The expressions <code>a[i]</code> and <code>a[j]</code> denote the same table element if and only if <code>i</code> and <code>j</code> are raw equal (that is, equal without metamethods). - - -<p> In particular, floats with integral values are equal to their respective integers (e.g., <code>1.0 == 1</code>). @@ -240,6 +241,9 @@ is converted to its respective integer. For instance, if you write <code>a[2.0] = true</code>, the actual key inserted into the table will be the integer <code>2</code>. +(On the other hand, +2 and "<code>2</code>" are different Lua values and therefore +denote different table entries.) <p> @@ -263,20 +267,21 @@ of a given value (see <a href="#6.1">§6.1</a>). <p> As will be discussed in <a href="#3.2">§3.2</a> and <a href="#3.3.3">§3.3.3</a>, -any reference to a global name <code>var</code> is syntactically translated -to <code>_ENV.var</code>. +any reference to a free name +(that is, a name not bound to any declaration) <code>var</code> +is syntactically translated to <code>_ENV.var</code>. Moreover, every chunk is compiled in the scope of -an external local variable called <code>_ENV</code> (see <a href="#3.3.2">§3.3.2</a>), -so <code>_ENV</code> itself is never a global name in a chunk. +an external local variable named <code>_ENV</code> (see <a href="#3.3.2">§3.3.2</a>), +so <code>_ENV</code> itself is never a free name in a chunk. <p> Despite the existence of this external <code>_ENV</code> variable and -the translation of global names, +the translation of free names, <code>_ENV</code> is a completely regular name. In particular, you can define new variables and parameters with that name. -Each reference to a global name uses the <code>_ENV</code> that is +Each reference to a free name uses the <code>_ENV</code> that is visible at that point in the program, following the usual visibility rules of Lua (see <a href="#3.5">§3.5</a>). @@ -288,34 +293,25 @@ Any table used as the value of <code>_ENV</code> is called an <em>environment</e <p> Lua keeps a distinguished environment called the <em>global environment</em>. This value is kept at a special index in the C registry (see <a href="#4.5">§4.5</a>). -In Lua, the variable <a href="#pdf-_G"><code>_G</code></a> is initialized with this same value. +In Lua, the global variable <a href="#pdf-_G"><code>_G</code></a> is initialized with this same value. +(<a href="#pdf-_G"><code>_G</code></a> is never used internally.) <p> -When Lua compiles a chunk, -it initializes the value of its <code>_ENV</code> upvalue -with the global environment (see <a href="#pdf-load"><code>load</code></a>). +When Lua loads a chunk, +the default value for its <code>_ENV</code> upvalue +is the global environment (see <a href="#pdf-load"><code>load</code></a>). Therefore, by default, -global variables in Lua code refer to entries in the global environment. +free names in Lua code refer to entries in the global environment +(and, therefore, they are also called <em>global variables</em>). Moreover, all standard libraries are loaded in the global environment -and several functions there operate on that environment. +and some functions there operate on that environment. You can use <a href="#pdf-load"><code>load</code></a> (or <a href="#pdf-loadfile"><code>loadfile</code></a>) to load a chunk with a different environment. (In C, you have to load the chunk and then change the value of its first upvalue.) -<p> -If you change the global environment in the registry -(through C code or the debug library), -all chunks loaded after the change will get the new environment. -Previously loaded chunks are not affected, however, -as each has its own reference to the environment in its <code>_ENV</code> variable. -Moreover, the variable <a href="#pdf-_G"><code>_G</code></a> -(which is stored in the original global environment) -is never updated by Lua. - - @@ -325,7 +321,7 @@ is never updated by Lua. Because Lua is an embedded extension language, all Lua actions start from C code in the host program calling a function from the Lua library. -(when you use Lua standalone, +(When you use Lua standalone, the <code>lua</code> application is the host program.) Whenever an error occurs during the compilation or execution of a Lua chunk, @@ -346,9 +342,10 @@ to call a given function in <em>protected mode</em>. Whenever there is an error, an <em>error object</em> (also called an <em>error message</em>) is propagated with information about the error. -Lua itself only generates errors where the error object is a string, +Lua itself only generates errors whose error object is a string, but programs may generate errors with -any value for the error object. +any value as the error object. +It is up to the Lua program or its host to handle such error objects. <p> @@ -363,7 +360,8 @@ for instance by inspecting the stack and creating a stack traceback. This message handler is still protected by the protected call; so, an error inside the message handler will call the message handler again. -If this loop goes on, Lua breaks it and returns an appropriate message. +If this loop goes on for too long, +Lua breaks it and returns an appropriate message. @@ -400,7 +398,7 @@ using the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function. You can replace the metatable of tables using the <a href="#pdf-setmetatable"><code>setmetatable</code></a> function. You cannot change the metatable of other types from Lua -(except by using the debug library); +(except by using the debug library (<a href="#6.10">§6.10</a>)); you must use the C API for that. @@ -416,10 +414,10 @@ but the string library sets a metatable for the string type (see <a href="#6.4"> <p> A metatable controls how an object behaves in -arithmetic and bitwise operations, +arithmetic operations, bitwise operations, order comparisons, concatenation, length operation, calls, and indexing. A metatable also can define a function to be called -when a userdata or a table is garbage collected. +when a userdata or a table is garbage collected (<a href="#2.5">§2.5</a>). <p> @@ -460,13 +458,13 @@ Lua will try to call a metamethod. First, Lua will check the first operand (even if it is valid). If that operand does not define a metamethod for the "<code>__add</code>" event, then Lua will check the second operand. -If Lua cannot find a metamethod, -it raises an error. -Otherwise, +If Lua can find a metamethod, it calls the metamethod with the two operands as arguments, and the result of the call (adjusted to one value) is the result of the operation. +Otherwise, +it raises an error. </li> <li><b>"sub": </b> @@ -647,7 +645,7 @@ and therefore can trigger another metamethod.) <p> -Whenever there is a metamethod, +Whenever there is a "newindex" metamethod, Lua does not perform the primitive assignment. (If necessary, the metamethod itself can call <a href="#pdf-rawset"><code>rawset</code></a> @@ -675,8 +673,8 @@ followed by the arguments of the original call (<code>args</code>). <p> Lua performs automatic memory management. This means that -you have to worry neither about allocating memory for new objects -nor about freeing it when the objects are no longer needed. +you do not have to worry about allocating memory for new objects +or freeing it when the objects are no longer needed. Lua manages memory automatically by running a <em>garbage collector</em> to collect all <em>dead objects</em> (that is, objects that are no longer accessible from Lua). @@ -710,7 +708,7 @@ memory allocation. Larger values make the collector more aggressive but also increase the size of each incremental step. You should not use values smaller than 100, -as they make the collector too slow and +because they make the collector too slow and can result in the collector never finishing a cycle. The default is 200, which means that the collector runs at "twice" @@ -758,7 +756,7 @@ and the metatable has a field indexed by the string "<code>__gc</code>". Note that if you set a metatable without a <code>__gc</code> field and later create that field in the metatable, the object will not be marked for finalization. -However, after an object is marked, +However, after an object has been marked, you can freely change the <code>__gc</code> field of its metatable. @@ -768,18 +766,18 @@ it is not collected immediately by the garbage collector. Instead, Lua puts it in a list. After the collection, Lua goes through that list: -For each object, +For each object in the list, it checks the object's <code>__gc</code> metamethod; if it is a function, Lua calls it with the object as its single argument. -(If the metamethod is not a function, -Lua simply ignores it.) +If the metamethod is not a function, +Lua simply ignores it. <p> At the end of each garbage-collection cycle, the finalizers for objects are called in -the reverse order that they were marked for finalization, +the reverse order that the objects were marked for finalization, among those collected in that cycle; that is, the first finalizer to be called is the one associated with the object marked last in the program. @@ -789,13 +787,13 @@ the execution of the regular code. <p> Because the object being collected must still be used by the finalizer, -it (and other objects accessible only through it) +that object (and other objects accessible only through it) must be <em>resurrected</em> by Lua. Usually, this resurrection is transient, and the object memory is freed in the next garbage-collection cycle. However, if the finalizer stores the object in some global place (e.g., a global variable), -then there is a permanent resurrection. +then the resurrection is permanent. Moreover, if the finalizer marks a finalizing object for finalization again, its finalizer will be called again in the next cycle where the object is unreachable. @@ -866,7 +864,7 @@ are removed from weak tables. Values, such as numbers and light C functions, are not subject to garbage collection, and therefore are not removed from weak tables -(unless its associated value is collected). +(unless their associated values are collected). Although strings are subject to garbage collection, they do not have an explicit construction, and therefore are not removed from weak tables. @@ -921,8 +919,8 @@ passing as its first argument a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, the coroutine starts its execution, at the first line of its main function. -Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on -to the coroutine main function. +Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed +as arguments to the coroutine's main function. After the coroutine starts running, it runs until it terminates or <em>yields</em>. @@ -932,7 +930,8 @@ A coroutine can terminate its execution in two ways: normally, when its main function returns (explicitly or implicitly, after the last instruction); and abnormally, if there is an unprotected error. -In the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>, +In case of normal termination, +<a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>, plus any values returned by the coroutine main function. In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b> plus an error message. @@ -1113,15 +1112,17 @@ into the string contents. <p> -A byte in a literal string can also be specified by its numerical value. -This can be done with the escape sequence <code>\x<em>XX</em></code>, +Strings in Lua can contain any 8-bit value, including embedded zeros, +which can be specified as '<code>\0</code>'. +More generally, +we can specify any byte in a literal string by its numerical value. +This can be done +with the escape sequence <code>\x<em>XX</em></code>, where <em>XX</em> is a sequence of exactly two hexadecimal digits, or with the escape sequence <code>\<em>ddd</em></code>, where <em>ddd</em> is a sequence of up to three decimal digits. -(Note that if a decimal escape is to be followed by a digit, +(Note that if a decimal escape sequence is to be followed by a digit, it must be expressed using exactly three digits.) -Strings in Lua can contain any 8-bit value, including embedded zeros, -which can be specified as '<code>\0</code>'. <p> @@ -1147,7 +1148,7 @@ for instance, a closing long bracket of level 4 is written as <code>]====]</code>. A <em>long literal</em> starts with an opening long bracket of any level and ends at the first closing long bracket of the same level. -It can contain any text except a closing bracket of the proper level. +It can contain any text except a closing bracket of the same level. Literals in this bracketed form can run for several lines, do not interpret any escape sequences, and ignore long brackets of any other level. @@ -1189,7 +1190,8 @@ the five literal strings below denote the same string: </pre> <p> -A <em>numerical constant</em> can be written with an optional fractional part +A <em>numerical constant</em> (or <em>numeral</em>) +can be written with an optional fractional part and an optional decimal exponent, marked by a letter '<code>e</code>' or '<code>E</code>'. Lua also accepts hexadecimal constants, @@ -1390,8 +1392,9 @@ even if it does not use that variable. <p> A chunk can be stored in a file or in a string inside the host program. To execute a chunk, -Lua first precompiles the chunk into instructions for a virtual machine, -and then it executes the compiled code +Lua first \emph{loads} it, +precompiling the chunk's code into instructions for a virtual machine, +and then Lua executes the compiled code with an interpreter for the virtual machine. @@ -1438,7 +1441,7 @@ before the adjustment <p> The assignment statement first evaluates all its expressions -and only then are the assignments performed. +and only then the assignments are performed. Thus the code <pre> @@ -1474,7 +1477,7 @@ We use it here only for explanatory purposes.) <p> -An assignment to a global variable <code>x = val</code> +An assignment to a global name <code>x = val</code> is equivalent to the assignment <code>_ENV.x = val</code> (see <a href="#2.2">§2.2</a>). @@ -1555,7 +1558,8 @@ A <b>break</b> ends the innermost enclosing loop. <p> The <b>return</b> statement is used to return values -from a function or a chunk (which is a function in disguise). +from a function or a chunk +(which is an anonymous function). Functions can return more than one value, so the syntax for the <b>return</b> statement is @@ -1760,8 +1764,8 @@ The basic expressions in Lua are the following: <pre> exp ::= prefixexp exp ::= <b>nil</b> | <b>false</b> | <b>true</b> - exp ::= Number - exp ::= String + exp ::= Numeral + exp ::= LiteralString exp ::= functiondef exp ::= tableconstructor exp ::= ‘<b>...</b>’ @@ -1771,7 +1775,7 @@ The basic expressions in Lua are the following: </pre> <p> -Numbers and literal strings are explained in <a href="#3.1">§3.1</a>; +Numerals and literal strings are explained in <a href="#3.1">§3.1</a>; variables are explained in <a href="#3.2">§3.2</a>; function definitions are explained in <a href="#3.4.11">§3.4.11</a>; function calls are explained in <a href="#3.4.10">§3.4.10</a>; @@ -1789,7 +1793,7 @@ relational operators (see <a href="#3.4.4">§3.4.4</a>), logical operators ( and the concatenation operator (see <a href="#3.4.6">§3.4.6</a>). Unary operators comprise the unary minus (see <a href="#3.4.1">§3.4.1</a>), the unary bitwise not (see <a href="#3.4.2">§3.4.2</a>), -the unary logic <b>not</b> (see <a href="#3.4.5">§3.4.5</a>), +the unary logical <b>not</b> (see <a href="#3.4.5">§3.4.5</a>), and the unary <em>length operator</em> (see <a href="#3.4.7">§3.4.7</a>). @@ -1881,12 +1885,13 @@ so that it works for non-integer exponents too. Integer division (<code>//</code>) converts its operands to integers (see <a href="#3.4.3">§3.4.3</a>) and its result is always an integer. -The result is always rounded towards minus infinite (floor). +The result is always rounded towards minus infinite +(floor division). <p> Modulo is defined as the remainder of a division -that rounds the quotient towards minus infinite (floor). +that rounds the quotient towards minus infinite (floor division). <p> @@ -1935,7 +1940,7 @@ types and representations at run time. Most arithmetic operations applied to mixed numbers (integers and floats) convert the integer operand to a float; this is called the <em>usual rule</em>. -Float division always convert integer operands to floats; +Float division always converts integer operands to floats; integer division and bitwise operators always convert float operands to integers. The C API also converts both integers to floats and @@ -1978,8 +1983,8 @@ Then, the resulting number is converted to the required type <p> -The conversion from numbers to strings uses a human-readable, -non-specified format. +The conversion from numbers to strings uses a +non-specified human-readable format. For complete control over how numbers are converted to strings, use the <code>format</code> function from the string library (see <a href="#pdf-string.format"><code>string.format</code></a>). @@ -2267,7 +2272,7 @@ Arguments have the following syntax: <pre> args ::= ‘<b>(</b>’ [explist] ‘<b>)</b>’ args ::= tableconstructor - args ::= String + args ::= LiteralString </pre><p> All argument expressions are evaluated before the call. A call of the form <code>f{<em>fields</em>}</code> is @@ -2598,12 +2603,13 @@ you are responsible for ensuring consistency. In particular, <em>you are responsible for controlling stack overflow</em>. You can use the function <a href="#lua_checkstack"><code>lua_checkstack</code></a> -to ensure that the stack has extra slots when pushing new elements. +to ensure that the stack has enough space for pushing new elements. <p> Whenever Lua calls C, -it ensures that the stack has at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra slots. +it ensures that the stack has space for +at least <a name="pdf-LUA_MINSTACK"><code>LUA_MINSTACK</code></a> extra slots. <code>LUA_MINSTACK</code> is defined as 20, so that usually you do not have to worry about stack space unless your code has loops pushing elements onto the stack. @@ -2612,7 +2618,7 @@ unless your code has loops pushing elements onto the stack. <p> When you call a Lua function without a fixed number of results (see <a href="#lua_call"><code>lua_call</code></a>), -Lua ensures that the stack has enough size for all results, +Lua ensures that the stack has enough space for all results, but it does not ensure any extra space. So, before pushing anything in the stack after such a call you should use <a href="#lua_checkstack"><code>lua_checkstack</code></a>. @@ -2722,14 +2728,14 @@ by other libraries, to avoid collisions. Typically, you should use as key a string containing your library name, or a light userdata with the address of a C object in your code, or any Lua object created by your code. -As with global names, +As with variable names, string keys starting with an underscore followed by uppercase letters are reserved for Lua. <p> -The integer keys in the registry are used by the reference mechanism, -implemented by the auxiliary library, +The integer keys in the registry are used +by the reference mechanism (see <a href="#luaL_ref"><code>luaL_ref</code></a>) and by some predefined values. Therefore, integer keys must not be used for other purposes. @@ -2759,8 +2765,8 @@ the global environment. <p> Internally, Lua uses the C <code>longjmp</code> facility to handle errors. -(You can also choose to use exceptions if you compile Lua as C++; -search for <code>LUAI_THROW</code> in the source code.) +(Lua will use exceptions if you compile it as C++; +search for <code>LUAI_THROW</code> in the source code for details.) When Lua faces any error (such as a memory allocation error, type errors, syntax errors, and runtime errors) @@ -2820,7 +2826,7 @@ Lua raises an error whenever it tries to yield across an API call, except for three functions: <a href="#lua_yieldk"><code>lua_yieldk</code></a>, <a href="#lua_callk"><code>lua_callk</code></a>, and <a href="#lua_pcallk"><code>lua_pcallk</code></a>. All those functions receive a <em>continuation function</em> -(as a parameter called <code>k</code>) to continue execution after a yield. +(as a parameter named <code>k</code>) to continue execution after a yield. <p> @@ -2864,7 +2870,7 @@ the Lua code being ran by <a href="#lua_pcall"><code>lua_pcall</code></a> to yie First, we can rewrite our function like here: <pre> - int k (lua_State *L, int status, lua_Ctx ctx) { + int k (lua_State *L, int status, lua_KContext ctx) { ... /* code 2 */ } @@ -2990,7 +2996,7 @@ Its arguments are <code>ptr</code>, a pointer to the block being allocated/reallocated/freed; <code>osize</code>, the original size of the block or some code about what is being allocated; -<code>nsize</code>, the new size of the block. +and <code>nsize</code>, the new size of the block. <p> @@ -3047,7 +3053,7 @@ It is used in the auxiliary library by <a href="#luaL_newstate"><code>luaL_newst </pre><p> Note that Standard C ensures that <code>free(NULL)</code> has no effect and that -<code>realloc(NULL, size)</code> is equivalent to <code>malloc(size)</code>. +<code>realloc(NULL,size)</code> is equivalent to <code>malloc(size)</code>. This code assumes that <code>realloc</code> does not fail when shrinking a block. (Although Standard C does not ensure this behavior, it seems to be a safe assumption.) @@ -3150,7 +3156,7 @@ Here it is in C: <pre> lua_getglobal(L, "f"); /* function to be called */ - lua_pushstring(L, "how"); /* 1st argument */ + lua_pushliteral(L, "how"); /* 1st argument */ lua_getglobal(L, "t"); /* table to be indexed */ lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */ lua_remove(L, -2); /* remove 't' from the stack */ @@ -3158,7 +3164,7 @@ Here it is in C: lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */ lua_setglobal(L, "a"); /* set global 'a' */ </pre><p> -Note that the code above is "balanced": +Note that the code above is <em>balanced</em>: at its end, the stack is back to its original configuration. This is considered good programming practice. @@ -3168,7 +3174,10 @@ This is considered good programming practice. <hr><h3><a name="lua_callk"><code>lua_callk</code></a></h3><p> <span class="apii">[-(nargs + 1), +nresults, <em>e</em>]</span> -<pre>void lua_callk (lua_State *L, int nargs, int nresults, lua_Ctx ctx, +<pre>void lua_callk (lua_State *L, + int nargs, + int nresults, + lua_KContext ctx, lua_KFunction k);</pre> <p> @@ -3207,16 +3216,16 @@ many results. <p> As an example, the following function receives a variable number -of numerical arguments and returns their average and sum: +of numerical arguments and returns their average and their sum: <pre> static int foo (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ - lua_Number sum = 0; + lua_Number sum = 0.0; int i; for (i = 1; i <= n; i++) { if (!lua_isnumber(L, i)) { - lua_pushstring(L, "incorrect argument"); + lua_pushliteral(L, "incorrect argument"); lua_error(L); } sum += lua_tonumber(L, i); @@ -3232,14 +3241,15 @@ of numerical arguments and returns their average and sum: <hr><h3><a name="lua_checkstack"><code>lua_checkstack</code></a></h3><p> <span class="apii">[-0, +0, –]</span> -<pre>int lua_checkstack (lua_State *L, int extra);</pre> +<pre>int lua_checkstack (lua_State *L, int n);</pre> <p> -Ensures that there are at least <code>extra</code> free stack slots in the stack. +Ensures that the stack has space for at least <code>n</code> extra slots. It returns false if it cannot fulfill the request, -because it would cause the stack to be larger than a fixed maximum size -(typically at least a few thousand elements) or -because it cannot allocate memory for the new stack size. +either because it would cause the stack +to be larger than a fixed maximum size +(typically at least several thousand elements) or +because it cannot allocate memory for the extra space. This function never shrinks the stack; if the stack is already larger than the new size, it is left unchanged. @@ -3260,7 +3270,7 @@ On several platforms, you may not need to call this function, because all resources are naturally released when the host program ends. On the other hand, long-running programs that create multiple states, such as daemons or web servers, -might need to close states as soon as they are not needed. +will probably need to close states as soon as they are not needed. @@ -3277,7 +3287,7 @@ when compared with the value at index <code>index2</code>, following the semantics of the corresponding Lua operator (that is, it may call metamethods). Otherwise returns 0. -Also returns 0 if any of the indices is non valid. +Also returns 0 if any of the indices is not valid. <p> @@ -3317,9 +3327,9 @@ Concatenation is performed following the usual semantics of Lua <p> Copies the element at index <code>fromidx</code> -into the valid index <code>toidx</code> -without shifting any element -(therefore replacing the value at that position). +into the valid index <code>toidx</code>, +replacing the value at that position. +Values at other positions are not affected. @@ -3344,21 +3354,6 @@ Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</c -<hr><h3><a name="lua_Ctx"><code>lua_Ctx</code></a></h3> -<pre>typedef ... lua_Ctx;</pre> - -<p> -The type for continuation-function contexts. -It must be a numerical type. -This type is defined as <code>intptr_t</code> -when <code>intptr_t</code> is available, -so that it can store pointers too. -Otherwise, it is defined as <code>ptrdiff_t</code>. - - - - - <hr><h3><a name="lua_dump"><code>lua_dump</code></a></h3><p> <span class="apii">[-0, +0, <em>e</em>]</span> <pre>int lua_dump (lua_State *L, @@ -3402,8 +3397,8 @@ This function does not pop the Lua function from the stack. <pre>int lua_error (lua_State *L);</pre> <p> -Generates a Lua error. -The error object must be on the stack top. +Generates a Lua error, +using the value at the top of the stack as the error object. This function does a long jump, and therefore never returns (see <a href="#luaL_error"><code>luaL_error</code></a>). @@ -3485,7 +3480,7 @@ see <a href="#pdf-collectgarbage"><code>collectgarbage</code></a>. <p> Returns the memory-allocation function of a given state. If <code>ud</code> is not <code>NULL</code>, Lua stores in <code>*ud</code> the -opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>. +opaque pointer given when the memory-allocator function was set. @@ -3546,6 +3541,24 @@ Returns the type of that value. +<hr><h3><a name="lua_geti"><code>lua_geti</code></a></h3><p> +<span class="apii">[-0, +1, <em>e</em>]</span> +<pre>int lua_geti (lua_State *L, int index, lua_Integer i);</pre> + +<p> +Pushes onto the stack the value <code>t[i]</code>, +where <code>t</code> is the value at the given index. +As in Lua, this function may trigger a metamethod +for the "index" event (see <a href="#2.4">§2.4</a>). + + +<p> +Returns the type of the pushed value. + + + + + <hr><h3><a name="lua_getmetatable"><code>lua_getmetatable</code></a></h3><p> <span class="apii">[-0, +(0|1), –]</span> <pre>int lua_getmetatable (lua_State *L, int index);</pre> @@ -3571,8 +3584,8 @@ and <code>k</code> is the value at the top of the stack. <p> -This function pops the key from the stack -(putting the resulting value in its place). +This function pops the key from the stack, +pushing the resulting value in its place. As in Lua, this function may trigger a metamethod for the "index" event (see <a href="#2.4">§2.4</a>). @@ -3591,8 +3604,8 @@ Returns the type of the pushed value. <p> 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 -(and so 0 means an empty stack). +this result is equal to the number of elements in the stack; +in particular, 0 means an empty stack. @@ -3636,10 +3649,10 @@ The type of integers in Lua. <p> -By default this type is <code>long long</code> +By default this type is <code>long long</code>, (usually a 64-bit two-complement integer), -but that can be changed to <code>long</code> or <code>int</code>, -usually a 32-bit two-complement integer. +but that can be changed to <code>long</code> or <code>int</code> +(usually a 32-bit two-complement integer). (See <code>LUA_INT</code> in <code>luaconf.h</code>.) @@ -3824,8 +3837,23 @@ and 0 otherwise. +<hr><h3><a name="lua_KContext"><code>lua_KContext</code></a></h3> +<pre>typedef ... lua_KContext;</pre> + +<p> +The type for continuation-function contexts. +It must be a numerical type. +This type is defined as <code>intptr_t</code> +when <code>intptr_t</code> is available, +so that it can store pointers too. +Otherwise, it is defined as <code>ptrdiff_t</code>. + + + + + <hr><h3><a name="lua_KFunction"><code>lua_KFunction</code></a></h3> -<pre>typedef int (*lua_KFunction) (lua_State *L, int status, lua_Ctx ctx);</pre> +<pre>typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);</pre> <p> Type for continuation functions (see <a href="#4.7">§4.7</a>). @@ -3839,8 +3867,9 @@ Type for continuation functions (see <a href="#4.7">§4.7</a>). <pre>void lua_len (lua_State *L, int index);</pre> <p> -Returns the "length" of the value at the given index; -it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.7">§3.4.7</a>). +Returns the length of the value at the given index. +It is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.7">§3.4.7</a>) and +may trigger a metamethod for the "length" event (see <a href="#2.4">§2.4</a>). The result is pushed on the stack. @@ -3856,7 +3885,7 @@ The result is pushed on the stack. const char *mode);</pre> <p> -Loads a Lua chunk (without running it). +Loads a Lua chunk without running it. If there are no errors, <code>lua_load</code> pushes the compiled chunk as a Lua function on top of the stack. @@ -4147,7 +4176,7 @@ error while running a <code>__gc</code> metamethod. int nargs, int nresults, int errfunc, - lua_Ctx ctx, + lua_KContext ctx, lua_KFunction k);</pre> <p> @@ -4275,7 +4304,7 @@ The conversion specifiers can only be '<code>%p</code>' (inserts a pointer as a hexadecimal numeral), '<code>%d</code>' (inserts an <code>int</code>), '<code>%c</code>' (inserts an <code>int</code> as a one-byte character), and -'<code>%U</code>' (inserts an <code>int</code> as a UTF-8 byte sequence). +'<code>%U</code>' (inserts a <code>long int</code> as a UTF-8 byte sequence). </li> </ul> @@ -4452,7 +4481,7 @@ Returns 1 if the two values in indices <code>index1</code> and <code>index2</code> are primitively equal (that is, without calling metamethods). Otherwise returns 0. -Also returns 0 if any of the indices are non valid. +Also returns 0 if any of the indices are not valid. @@ -4538,10 +4567,10 @@ Similar to <a href="#lua_settable"><code>lua_settable</code></a>, but does a raw <hr><h3><a name="lua_rawseti"><code>lua_rawseti</code></a></h3><p> <span class="apii">[-1, +0, <em>e</em>]</span> -<pre>void lua_rawseti (lua_State *L, int index, lua_Integer n);</pre> +<pre>void lua_rawseti (lua_State *L, int index, lua_Integer i);</pre> <p> -Does the equivalent of <code>t[n] = v</code>, +Does the equivalent of <code>t[i] = v</code>, where <code>t</code> is the table at the given index and <code>v</code> is the value at the top of the stack. @@ -4747,6 +4776,25 @@ sets it as the new value of global <code>name</code>. +<hr><h3><a name="lua_seti"><code>lua_seti</code></a></h3><p> +<span class="apii">[-1, +0, <em>e</em>]</span> +<pre>void lua_seti (lua_State *L, int index, lua_Integer n);</pre> + +<p> +Does the equivalent to <code>t[n] = v</code>, +where <code>t</code> is the value at the given index +and <code>v</code> is the value at the top of the stack. + + +<p> +This function pops the value from the stack. +As in Lua, this function may trigger a metamethod +for the "newindex" event (see <a href="#2.4">§2.4</a>). + + + + + <hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p> <span class="apii">[-1, +0, –]</span> <pre>void lua_setmetatable (lua_State *L, int index);</pre> @@ -4851,20 +4899,22 @@ You can resume threads with status <a href="#pdf-LUA_OK"><code>LUA_OK</code></a> -<hr><h3><a name="lua_strtonum"><code>lua_strtonum</code></a></h3><p> +<hr><h3><a name="lua_stringtonumber"><code>lua_stringtonumber</code></a></h3><p> <span class="apii">[-0, +1, –]</span> -<pre>size_t lua_strtonum (lua_State *L, const char *s);</pre> +<pre>size_t lua_stringtonumber (lua_State *L, const char *s);</pre> <p> Converts the zero-terminated string <code>s</code> to a number, pushes that number into the stack, -and returns the total size of the string -(that is, its length plus one). +and returns the total size of the string, +that is, its length plus one. The conversion can result in an integer or a float, according to the lexical conventions of Lua (see <a href="#3.1">§3.1</a>). The string may have leading and trailing spaces and a sign. If the string is not a valid numeral, returns 0 and pushes nothing. +(Note that the result can be used as a boolean, +true if the conversion succeeds.) @@ -5190,7 +5240,10 @@ the function calling <code>lua_yield</code>. <hr><h3><a name="lua_yieldk"><code>lua_yieldk</code></a></h3><p> <span class="apii">[-?, +?, <em>e</em>]</span> -<pre>int lua_yieldk (lua_State *L, int nresults, lua_Ctx ctx, lua_KFunction k);</pre> +<pre>int lua_yieldk (lua_State *L, + int nresults, + lua_KContext ctx, + lua_KFunction k);</pre> <p> Yields a coroutine (thread). @@ -6052,19 +6105,6 @@ of any type (including <b>nil</b>) at position <code>arg</code>. -<hr><h3><a name="luaL_checkint"><code>luaL_checkint</code></a></h3><p> -<span class="apii">[-0, +0, <em>v</em>]</span> -<pre>int luaL_checkint (lua_State *L, int arg);</pre> - -<p> -Checks whether the function argument <code>arg</code> is an integer -(or can be converted to an integer) -and returns this integer cast to an <code>int</code>. - - - - - <hr><h3><a name="luaL_checkinteger"><code>luaL_checkinteger</code></a></h3><p> <span class="apii">[-0, +0, <em>v</em>]</span> <pre>lua_Integer luaL_checkinteger (lua_State *L, int arg);</pre> @@ -6078,19 +6118,6 @@ and returns this integer cast to a <a href="#lua_Integer"><code>lua_Integer</cod -<hr><h3><a name="luaL_checklong"><code>luaL_checklong</code></a></h3><p> -<span class="apii">[-0, +0, <em>v</em>]</span> -<pre>long luaL_checklong (lua_State *L, int arg);</pre> - -<p> -Checks whether the function argument <code>arg</code> is an integer -(or can be converted to an integer) -and returns this integer cast to a <code>long</code>. - - - - - <hr><h3><a name="luaL_checklstring"><code>luaL_checklstring</code></a></h3><p> <span class="apii">[-0, +0, <em>v</em>]</span> <pre>const char *luaL_checklstring (lua_State *L, int arg, size_t *l);</pre> @@ -6316,10 +6343,10 @@ file-related functions in the standard library <p> Pushes onto the stack the field <code>e</code> from the metatable -of the object at index <code>obj</code>. +of the object at index <code>obj</code> and returns the type of pushed value. If the object does not have a metatable, or if the metatable does not have this field, -returns false and pushes nothing. +pushes nothing and returns <code>LUA_TNIL</code>. @@ -6490,16 +6517,22 @@ it does not run it. <hr><h3><a name="luaL_newlib"><code>luaL_newlib</code></a></h3><p> <span class="apii">[-0, +1, <em>e</em>]</span> -<pre>void luaL_newlib (lua_State *L, const luaL_Reg *l);</pre> +<pre>void luaL_newlib (lua_State *L, const luaL_Reg l[]);</pre> <p> Creates a new table and registers there the functions in list <code>l</code>. + + +<p> It is implemented as the following macro: <pre> (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) -</pre> +</pre><p> +The array <code>l</code> must be the actual array, +not a pointer to it. + @@ -6579,21 +6612,6 @@ Opens all standard Lua libraries into the given state. -<hr><h3><a name="luaL_optint"><code>luaL_optint</code></a></h3><p> -<span class="apii">[-0, +0, <em>v</em>]</span> -<pre>int luaL_optint (lua_State *L, int arg, int d);</pre> - -<p> -If the function argument <code>arg</code> is a number, -returns this number cast to an <code>int</code>. -If this argument is absent or is <b>nil</b>, -returns <code>d</code>. -Otherwise, raises an error. - - - - - <hr><h3><a name="luaL_optinteger"><code>luaL_optinteger</code></a></h3><p> <span class="apii">[-0, +0, <em>v</em>]</span> <pre>lua_Integer luaL_optinteger (lua_State *L, @@ -6612,22 +6630,6 @@ Otherwise, raises an error. -<hr><h3><a name="luaL_optlong"><code>luaL_optlong</code></a></h3><p> -<span class="apii">[-0, +0, <em>v</em>]</span> -<pre>long luaL_optlong (lua_State *L, int arg, long d);</pre> - -<p> -If the function argument <code>arg</code> is an integer -(or convertible to an integer), -returns this integer cast to a <code>long</code>. -If this argument is absent or is <b>nil</b>, -returns <code>d</code>. -Otherwise, raises an error. - - - - - <hr><h3><a name="luaL_optlstring"><code>luaL_optlstring</code></a></h3><p> <span class="apii">[-0, +0, <em>v</em>]</span> <pre>const char *luaL_optlstring (lua_State *L, @@ -6870,7 +6872,8 @@ this function receives the file handle as its sole argument and must return either <b>true</b> (in case of success) or <b>nil</b> plus an error message (in case of error). Once Lua calls this field, -the field value is changed to <b>nil</b> to signal that the handle is closed. +the field value is changed to <code>NULL</code> +to signal that the handle is closed. @@ -7210,12 +7213,8 @@ so that the construction for i,v in ipairs(t) do <em>body</em> end </pre><p> will iterate over the pairs -(<code>1,t[1]</code>), (<code>2,t[2]</code>), ..., (<code>#t,t[#t]</code>). - - -<p> -The table should be a proper sequence -or have a <code>__len</code> metamethod (see <a href="#3.4.7">§3.4.7</a>). +(<code>1,t[1]</code>), (<code>2,t[2]</code>), ..., +up to the first integer key absent from the table. @@ -7251,7 +7250,8 @@ or to the value of the global environment. (When you load a main chunk, the resulting function will always have exactly one upvalue, the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>). -When you load a binary chunk created from a function (see <a href="#pdf-string.dump"><code>string.dump</code></a>), +However, +when you load a binary chunk created from a function (see <a href="#pdf-string.dump"><code>string.dump</code></a>), the resulting function can have arbitrary upvalues.) @@ -7774,7 +7774,7 @@ Default is '<code>?</code>'.</li> is replaced by the executable's directory. Default is '<code>!</code>'.</li> -<li>The fifth line is a mark to ignore all text before it +<li>The fifth line is a mark to ignore all text after it when building the <code>luaopen_</code> function name. Default is '<code>-</code>'.</li> @@ -7956,7 +7956,7 @@ The name of this C function is the string "<code>luaopen_</code>" concatenated with a copy of the module name where each dot is replaced by an underscore. Moreover, if the module name has a hyphen, -its sufix after (and including) the first hyphen is removed. +its suffix after (and including) the first hyphen is removed. For instance, if the module name is <code>a.b.c-v2.1</code>, the function name will be <code>luaopen_a_b_c</code>. @@ -8104,47 +8104,6 @@ about the function <p> -<hr><h3><a name="pdf-string.dumpfloat"><code>string.dumpfloat (n [, size [, endianness]])</code></a></h3> -Returns a string with the machine representation of float <code>n</code>, -with given size and endianness. -The <code>size</code> is the string "<code>f</code>" (single precision), -"<code>d</code>" (double precision), or "<code>n</code>", -which means the size of a <a href="#lua_Number"><code>lua_Number</code></a>; -its default is "<code>n</code>". -The endianness is the string "<code>l</code>" (little endian), "<code>b</code>" (big endian), -or "<code>n</code>" (native); -the default is the native endianness. - - -<p> -This function may not work correctly in architectures -with mixed endian. - - - - -<p> -<hr><h3><a name="pdf-string.dumpint"><code>string.dumpint (n [, size [, endianness]])</code></a></h3> -Returns a string with the two-complement representation of integer <code>n</code>, -with <code>size</code> bytes and given endianness. -The <code>size</code> can be any value from 1 to 12, -or 0, which means the size of a <a href="#lua_Integer"><code>lua_Integer</code></a> -(8 bytes in standard Lua); -its default is zero. -The endianness is the string "<code>l</code>" (little endian), "<code>b</code>" (big endian), -or "<code>n</code>" (native); -the default is the native endianness. - - -<p> -This function may not work correctly in architectures -with mixed endian or -that do not use a two-complement representation for integers. - - - - -<p> <hr><h3><a name="pdf-string.find"><code>string.find (s, pattern [, init [, plain]])</code></a></h3> @@ -8368,6 +8327,18 @@ its default value is 1 and can be negative. <p> +<hr><h3><a name="pdf-string.pack"><code>string.pack (fmt, v1, v2, ...)</code></a></h3> + + +<p> +Returns a binary string containing the values v1, v2, etc. +packed (that is, serialized in binary form) +according to the format string fmt (see <a href="#6.4.2">§6.4.2</a>). + + + + +<p> <hr><h3><a name="pdf-string.rep"><code>string.rep (s, n [, sep])</code></a></h3> Returns a string that is the concatenation of <code>n</code> copies of the string <code>s</code> separated by the string <code>sep</code>. @@ -8412,23 +8383,16 @@ the function returns the empty string. <p> -<hr><h3><a name="pdf-string.undumpfloat"><code>string.undumpfloat (s [, pos [, size [, endianness]]])</code></a></h3> -Reads the machine representation of a float starting at position -<code>pos</code> in string <code>s</code> and returns that number. -See <a href="#pdf-string.dumpfloat"><code>string.dumpfloat</code></a> for details about <code>size</code> and <code>endianness</code>. - - +<hr><h3><a name="pdf-string.unpack"><code>string.unpack (fmt, s [, pos])</code></a></h3> <p> -<hr><h3><a name="pdf-string.undumpint"><code>string.undumpint (s [, pos [, size [, endianness]]])</code></a></h3> -Reads the machine representation of an integer starting at position -<code>pos</code> in string <code>s</code> and returns that integer. -See <a href="#pdf-string.dumpint"><code>string.dumpint</code></a> for details about <code>size</code> and <code>endianness</code>. - - -<p> -Integers are always read as signed. +Returns the values packed in string <code>s</code> (see <a href="#pdf-string.pack"><code>string.pack</code></a>) +according to the format string <code>fmt</code> (see <a href="#6.4.2">§6.4.2</a>). +An optional <code>pos</code> marks where +to start reading in <code>s</code> (default is 1). +After the read values, +this function also returns the index of the first unread byte in <code>s</code>. @@ -8495,7 +8459,8 @@ represents the character <em>x</em> itself. <li><b><code>%<em>x</em></code>: </b> (where <em>x</em> is any non-alphanumeric character) represents the character <em>x</em>. This is the standard way to escape the magic characters. -Any punctuation character (even the non magic) +Any non-alphanumeric character +(including all punctuations, even the non-magical) can be preceded by a '<code>%</code>' when used to represent itself in a pattern. </li> @@ -8646,6 +8611,85 @@ string <code>"flaaap"</code>, there will be two captures: 3 and 5. +<h3>6.4.2 – <a name="6.4.2">Format Strings for Pack and Unpack</a></h3> + +<p> +The first argument to both <a href="#pdf-string.pack"><code>string.pack</code></a> and <a href="#pdf-string.unpack"><code>string.unpack</code></a> +is a format string, +which describes the layout of the structure being created or read. + + +<p> +A format string is a sequence of conversion options. +The conversion options are as follows: +<table border="1"> +<tr><td><code><</code></td><td>sets little endian</td></tr> +<tr><td><code>></code></td><td>sets big endian</td></tr> +<tr><td><code>![<em>n</em>]</code></td><td>sets maximum alignment to <code>n</code> +(default is native alignment)</td></tr> +<tr><td><code>b</code></td><td>a signed byte (<code>char</code>)</td></tr> +<tr><td><code>B</code></td><td>an unsigned byte (<code>char</code>)</td></tr> +<tr><td><code>h</code></td><td>a signed <code>short</code> (native size)</td></tr> +<tr><td><code>H</code></td><td>an unsigned <code>short</code> (native size)</td></tr> +<tr><td><code>l</code></td><td>a signed <code>long</code> (native size)</td></tr> +<tr><td><code>L</code></td><td>an unsigned <code>long</code> (native size)</td></tr> +<tr><td><code>j</code></td><td>a <code>lua_Integer</code></td></tr> +<tr><td><code>J</code></td><td>a <code>lua_Unsigned</code></td></tr> +<tr><td><code>T</code></td><td>a <code>size_t</code> (native size)</td></tr> +<tr><td><code>i[<em>n</em>]</code></td><td>a signed <code>int</code> with <code>n</code> bytes +(default is native size)</td></tr> +<tr><td><code>I[<em>n</em>]</code></td><td>an unsigned <code>int</code> with <code>n</code> bytes +(default is native size)</td></tr> +<tr><td><code>f</code></td><td>a <code>float</code> (native size)</td></tr> +<tr><td><code>d</code></td><td>a <code>double</code> (native size)</td></tr> +<tr><td><code>n</code></td><td>a <code>lua_Number</code></td></tr> +<tr><td><code>c[<em>n</em>]</code></td><td>a fixed-sized string with <code>n</code> bytes +(default is 1)</td></tr> +<tr><td><code>z</code></td><td>a zero-terminated string</td></tr> +<tr><td><code>s[<em>n</em>]</code></td><td>a string preceded by its length +coded as an unsigned integer with <code>n</code> bytes +(default is a <code>size_t</code>)</td></tr> +<tr><td><code>x</code></td><td>one byte of padding</td></tr> +<tr><td><code>X<em>op</em></code></td><td>an empty item that aligns +according to option <code>op</code> +(which is otherwise ignored)</td></tr> +<tr><td>'<code> </code>'</td><td>(empty space) ignored</td></tr> +</table> +(A "<code>[<em>n</em>]</code>" means an optional integral numeral.) +Except for padding, spaces, and configurations +(options "<code>xX <>!</code>"), +each option corresponds to an argument (in <a href="#pdf-string.pack"><code>string.pack</code></a>) +or a result (in <a href="#pdf-string.unpack"><code>string.unpack</code></a>). + + +<p> +For options "<code>!<em>n</em></code>", "<code>s<em>n</em></code>", "<code>i<em>n</em></code>", and "<code>I<em>n</em></code>", +<code>n</code> can be any integer between 1 and 16. +All integral options check overflows; +<a href="#pdf-string.pack"><code>string.pack</code></a> checks whether the given value fits in the given size; +<a href="#pdf-string.unpack"><code>string.unpack</code></a> checks whether the read value fits in a Lua integer. + + +<p> +Before any configuration option, +the default alignment is 1 (that is, no alignment) +and the default endianness is the native endianness. + + +<p> +Alignment works as follows: +For each option, +the format gets extra padding until the data starts +at an offset that is a multiple of the minimum between the +option size and the maximum alignment. +This minimum must be a power of 2 (1, 2, 4, 8, or 16). +Options "<code>c</code>" and "<code>z</code>" are not aligned. +Option "<code>s</code>" is aligned according to the size of its starting length. + + + + + <h2>6.5 – <a name="6.5">UTF-8 Support</a></h2> @@ -8678,7 +8722,7 @@ and returns a string with the concatenation of all these sequences. <p> -<hr><h3><a name="pdf-utf8.charpatt"><code>utf8.charpatt</code></a></h3> +<hr><h3><a name="pdf-utf8.charpattern"><code>utf8.charpattern</code></a></h3> The pattern (a string, not a function) "<code>[\0-\x7F\xC2-\xF4][\x80-\xBF]*</code>" (see <a href="#6.4.1">§6.4.1</a>), which matches exactly one UTF-8 byte sequence, @@ -8721,7 +8765,7 @@ Returns the number of UTF-8 characters in string <code>s</code> that start between positions <code>i</code> and @{j} (both inclusive). The default for <code>i</code> is 1 and for <code>j</code> is -1. If it finds any invalid byte sequence, -returns <b>nil</b> plus the position of the first invalid byte. +returns a false value plus the position of the first invalid byte. @@ -8787,32 +8831,32 @@ If <code>i</code> is greater than <code>j</code>, returns the empty string. <p> -<hr><h3><a name="pdf-table.copy"><code>table.copy (a1, f, e, [a2,] t)</code></a></h3> +<hr><h3><a name="pdf-table.insert"><code>table.insert (list, [pos,] value)</code></a></h3> <p> -Copies elements from table <code>a1</code> to table <code>a2</code>. -This function performs the equivalent to the following -multiple assignment: -<code>a2[t],··· = a1[f],···,a1[e]</code>. -The default for <code>a2</code> is <code>a1</code>. -The destination range can overlap with the source range. -Index <code>f</code> must be positive. +Inserts element <code>value</code> at position <code>pos</code> in <code>list</code>, +shifting up the elements +<code>list[pos], list[pos+1], ···, list[#list]</code>. +The default value for <code>pos</code> is <code>#list+1</code>, +so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end +of list <code>t</code>. <p> -<hr><h3><a name="pdf-table.insert"><code>table.insert (list, [pos,] value)</code></a></h3> +<hr><h3><a name="pdf-table.move"><code>table.move (a1, f, e, t [,a2])</code></a></h3> <p> -Inserts element <code>value</code> at position <code>pos</code> in <code>list</code>, -shifting up the elements -<code>list[pos], list[pos+1], ···, list[#list]</code>. -The default value for <code>pos</code> is <code>#list+1</code>, -so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end -of list <code>t</code>. +Moves elements from table <code>a1</code> to table <code>a2</code>. +This function performs the equivalent to the following +multiple assignment: +<code>a2[t],··· = a1[f],···,a1[e]</code>. +The default for <code>a2</code> is <code>a1</code>. +The destination range can overlap with the source range. +Index <code>f</code> must be positive. @@ -8991,6 +9035,17 @@ Converts the angle <code>x</code> from radians to degrees. <p> +<hr><h3><a name="pdf-math.exp"><code>math.exp (x)</code></a></h3> + + +<p> +Returns the value <em>e<sup>x</sup></em> +(where <code>e</code> is the base of natural logarithms). + + + + +<p> <hr><h3><a name="pdf-math.floor"><code>math.floor (x)</code></a></h3> @@ -9482,6 +9537,8 @@ 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 <b>nil</b> if it cannot read data with the specified format. +(In this latter case, +the function does not read subsequent formats.) When called without formats, it uses a default format that reads the next line (see below). @@ -9919,32 +9976,6 @@ The default is always the current thread. <p> -<hr><h3><a name="pdf-debug.Csize"><code>debug.Csize (t)</code></a></h3> - - -<p> -Returns the size of the underlying representation of a given C type, -according to the following table: -<table border="1"> -<tr><td>'<code>I</code>'</td><td><code>lua_Integer</code></td></tr> -<tr><td>'<code>F</code>'</td><td><code>lua_Number</code></td></tr> -<tr><td>'<code>b</code>'</td><td><code>byte</code></td></tr> -<tr><td>'<code>d</code>'</td><td><code>double</code></td></tr> -<tr><td>'<code>f</code>'</td><td><code>float</code></td></tr> -<tr><td>'<code>h</code>'</td><td><code>short int</code></td></tr> -<tr><td>'<code>i</code>'</td><td><code>int</code></td></tr> -<tr><td>'<code>l</code>'</td><td><code>long int</code></td></tr> -<tr><td>'<code>z</code>'</td><td><code>size_t</code></td></tr> -</table> -For all options except '<code>b</code>', -the size is given in number of bytes; -for option '<code>b</code>', -the size is its number of bits. - - - - -<p> <hr><h3><a name="pdf-debug.debug"><code>debug.debug ()</code></a></h3> @@ -10222,7 +10253,7 @@ If <code>message</code> is present but is neither a string nor <b>nil</b>, this function returns <code>message</code> without further processing. Otherwise, it returns a string with a traceback of the call stack. -An optional <code>message</code> string is appended +The optional <code>message</code> string is appended at the beginning of the traceback. An optional <code>level</code> number tells at which level to start the traceback @@ -10384,12 +10415,11 @@ by issuing a different prompt. <p> In case of unprotected errors in the script, the interpreter reports the error to the standard error stream. -If the error object is a string, -the interpreter adds a stack traceback to it. -Otherwise, if the error object has a metamethod <code>__tostring</code>, +If the error object is not a string but +has a metamethod <code>__tostring</code>, the interpreter calls this metamethod to produce the final message. -Finally, if the error object is <b>nil</b>, -the interpreter does not report the error. +Otherwise, the interpreter converts the error object to a string +and adds a stack traceback to it. <p> @@ -10527,7 +10557,7 @@ for setting and getting elements. <li> The <a href="#pdf-ipairs"><code>ipairs</code></a> iterator now respects metamethods and -its id{__ipairs} metamethod has been deprecated. +its <code>__ipairs</code> metamethod has been deprecated. </li> <li> @@ -10544,7 +10574,8 @@ you can replace <code>math.atan2</code> with <code>math.atan</code>, which now accepts one or two parameters; you can replace <code>math.ldexp(x,exp)</code> with <code>x * 2.0^exp</code>. For the other operations, -the best choice is to use an external library. +you can either use an external library or +implement them in Lua. </li> <li> @@ -10582,11 +10613,20 @@ Use 0 as the value of this parameter to get the old behavior. <li> Functions to inject/project unsigned integers -(<code>lua_pushunsigned</code>, <code>lua_tounsigned</code>, etc.) +(<code>lua_pushunsigned</code>, <code>lua_tounsigned</code>, <code>lua_tounsignedx</code>, +<code>luaL_checkunsigned</code>, <code>luaL_optunsigned</code>) were deprecated. Use their signed equivalents with a type cast. </li> +<li> +Macros to project non-default integer types +(<code>luaL_checkint</code>, <code>luaL_optint</code>, <code>luaL_checklong</code>, <code>luaL_optlong</code>) +were deprecated. +Use their equivalent over <a href="#lua_Integer"><code>lua_Integer</code></a> with a type cast +(or, when possible, use <a href="#lua_Integer"><code>lua_Integer</code></a> in your code). +</li> + </ul> @@ -10596,7 +10636,13 @@ Use their signed equivalents with a type cast. <p> Here is the complete syntax of Lua in extended BNF. -(For operator precedences, see <a href="#3.4.8">§3.4.8</a>.) +As usual in extended BNF, +{A} means 0 or more As, +and [A] means an optional A. +(For operator precedences, see <a href="#3.4.8">§3.4.8</a>; +for a description of the terminals +Name, Numeral, +and LiteralString, see <a href="#3.1">§3.1</a>.) @@ -10637,14 +10683,14 @@ Here is the complete syntax of Lua in extended BNF. explist ::= exp {‘<b>,</b>’ exp} - exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | ‘<b>...</b>’ | functiondef | + exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Numeral | LiteralString | ‘<b>...</b>’ | functiondef | prefixexp | tableconstructor | exp binop exp | unop exp prefixexp ::= var | functioncall | ‘<b>(</b>’ exp ‘<b>)</b>’ functioncall ::= prefixexp args | prefixexp ‘<b>:</b>’ Name args - args ::= ‘<b>(</b>’ [explist] ‘<b>)</b>’ | tableconstructor | String + args ::= ‘<b>(</b>’ [explist] ‘<b>)</b>’ | tableconstructor | LiteralString functiondef ::= <b>function</b> funcbody @@ -10681,10 +10727,10 @@ Here is the complete syntax of Lua in extended BNF. <HR> <SMALL CLASS="footer"> Last update: -Thu Jul 31 14:02:14 BRT 2014 +Thu Oct 23 09:03:14 BRST 2014 </SMALL> <!-- -Last change: revised for Lua 5.3.0 (alpha) +Last change: revised for Lua 5.3.0 (beta) --> </body></html> diff --git a/doc/readme.html b/doc/readme.html index 19e0c553..1cba776e 100644 --- a/doc/readme.html +++ b/doc/readme.html @@ -31,12 +31,12 @@ tt, kbd, code { <HR> <H1> <A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A> -Welcome to Lua 5.3 (alpha) +Welcome to Lua 5.3 (beta) </H1> <P> <IMG SRC="alert.png" ALIGN="absbottom"> -<EM>Some details may change in the final version.</EM> +<EM>A few details may change in the final version.</EM> <P> <A HREF="#about">about</A> @@ -114,7 +114,7 @@ Here are the details. <OL> <LI> Open a terminal window and move to -the top-level directory, which is named <TT>lua-5.3.0-alpha</TT>. +the top-level directory, which is named <TT>lua-5.3.0-beta</TT>. The <TT>Makefile</TT> there controls both the build process and the installation process. <P> <LI> @@ -271,13 +271,11 @@ lists the <H3>Main changes</H3> <UL> -<LI> support for integers (64-bit by default) -<LI> better support for small architectures ("Small Lua" with 32-bit numbers) +<LI> integers (64-bit by default) +<LI> official support for small architectures ("Small Lua" with 32-bit numbers) <LI> bitwise operators -<LI> basic utf-8 library +<LI> basic utf-8 support -<LI> utf-8 escapes in literal strings -<LI> strip option in <CODE>lua_dump</CODE>/<CODE>string.dump</CODE> </UL> Here are the other changes introduced in Lua 5.3: @@ -286,20 +284,33 @@ Here are the other changes introduced in Lua 5.3: <LI> userdata can have any Lua value as uservalue <LI> integer division <LI> more flexible rules for some metamethods +<LI> utf-8 escapes in literal strings </UL> <H3>Libraries</H3> <UL> -<LI> functions for packing/unpacking numbers +<LI> basic utf-8 library +<LI> <CODE>ipairs</CODE> and the table library respect metamethods +<LI> functions for packing and unpacking numbers <LI> strip option in <CODE>string.dump</CODE> <LI> table library respects metamethods <LI> new function <CODE>table.copy</CODE> -<LI> new function <CODE>debug.Csize</CODE> +<LI> new function <CODE>debug.sizeof</CODE> +<LI> strip option in +<CODE>string.dump</CODE> +and +<CODE>lua_dump</CODE> </UL> <H3>C API</H3> <UL> -<LI> new functions: <CODE>lua_rotate</CODE>, <CODE>lua_isyieldable</CODE>, <CODE>lua_strtonum</CODE> +<LI> simpler API for continuation functions in C +<LI> new functions: +<CODE>lua_rotate</CODE>, +<CODE>lua_isyieldable</CODE>, +<CODE>lua_strtonum</CODE>, +<CODE>lua_geti</CODE>, +<CODE>lua_seti</CODE> <LI> <CODE>lua_gettable</CODE> and similar functions return type of resulted value </UL> @@ -356,10 +367,10 @@ THE SOFTWARE. <HR> <SMALL CLASS="footer"> Last update: -Thu Jul 31 15:23:46 BRT 2014 +Tue Oct 7 18:16:28 BRT 2014 </SMALL> <!-- -Last change: updated for Lua 5.3.0 (alpha) +Last change: updated for Lua 5.3.0 (beta) --> </BODY> diff --git a/src/Makefile b/src/Makefile index a30a75ef..7be16dc3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -92,7 +92,11 @@ aix: $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" ansi: - $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI -DLUA_32BITS" + @echo "" + @echo "Note: in ANSI mode, Lua is built with 32-bit numbers" + @echo " because ANSI C89 does not support 'long long'" + @echo "" bsd: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.232 2014/07/30 14:00:14 roberto Exp $ +** $Id: lapi.c,v 2.238 2014/10/17 19:17:55 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ @@ -332,7 +332,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { } -LUA_API size_t lua_strtonum (lua_State *L, const char *s) { +LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { size_t sz = luaO_str2num(s, L->top); if (sz != 0) api_incr_top(L); @@ -611,6 +611,18 @@ LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { } +LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + setivalue(L->top, n); + api_incr_top(L); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); + return ttnov(L->top - 1); +} + + LUA_API int lua_rawget (lua_State *L, int idx) { StkId t; lua_lock(L); @@ -664,7 +676,7 @@ LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { LUA_API int lua_getmetatable (lua_State *L, int objindex) { const TValue *obj; Table *mt = NULL; - int res; + int res = 0; lua_lock(L); obj = index2addr(L, objindex); switch (ttnov(obj)) { @@ -678,9 +690,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { mt = G(L)->mt[ttnov(obj)]; break; } - if (mt == NULL) - res = 0; - else { + if (mt != NULL) { sethvalue(L, L->top, mt); api_incr_top(L); res = 1; @@ -743,6 +753,18 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { } +LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { + StkId t; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + setivalue(L->top++, n); + luaV_settable(L, t, L->top - 1, L->top - 2); + L->top -= 2; /* pop value and key */ + lua_unlock(L); +} + + LUA_API void lua_rawset (lua_State *L, int idx) { StkId o; Table *t; @@ -854,8 +876,8 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) { "results from function overflow current stack size") -LUA_API void lua_callk (lua_State *L, int nargs, int nresults, lua_Ctx ctx, - lua_KFunction k) { +LUA_API void lua_callk (lua_State *L, int nargs, int nresults, + lua_KContext ctx, lua_KFunction k) { StkId func; lua_lock(L); api_check(k == NULL || !isLua(L->ci), @@ -894,7 +916,7 @@ static void f_call (lua_State *L, void *ud) { LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, - lua_Ctx ctx, lua_KFunction k) { + lua_KContext ctx, lua_KFunction k) { struct CallS c; int status; ptrdiff_t func; diff --git a/src/lauxlib.c b/src/lauxlib.c index abf589ae..0a6cea0a 100644 --- a/src/lauxlib.c +++ b/src/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.267 2014/07/19 14:37:09 roberto Exp $ +** $Id: lauxlib.c,v 1.270 2014/10/22 11:44:20 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -82,12 +82,12 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { static void pushfuncname (lua_State *L, lua_Debug *ar) { if (*ar->namewhat != '\0') /* is there a name? */ - lua_pushfstring(L, "function " LUA_QS, ar->name); + lua_pushfstring(L, "function '%s'", ar->name); else if (*ar->what == 'm') /* main? */ lua_pushliteral(L, "main chunk"); else if (*ar->what == 'C') { if (pushglobalfuncname(L, ar)) { - lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); + lua_pushfstring(L, "function '%s'", lua_tostring(L, -1)); lua_remove(L, -2); /* remove name */ } else @@ -158,25 +158,25 @@ LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) { if (strcmp(ar.namewhat, "method") == 0) { arg--; /* do not count `self' */ if (arg == 0) /* error is in the self argument itself? */ - return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + return luaL_error(L, "calling '%s' on bad self (%s)", ar.name, extramsg); } if (ar.name == NULL) ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; - return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", + return luaL_error(L, "bad argument #%d to '%s' (%s)", arg, ar.name, extramsg); } static int typeerror (lua_State *L, int arg, const char *tname) { const char *msg; - const char *typearg = luaL_typename(L, arg); - if (lua_getmetatable(L, arg)) { - if (lua_getfield(L, -1, "__name") == LUA_TSTRING) - typearg = lua_tostring(L, -1); - } + const char *typearg; /* name for the type of the actual argument */ + if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) + typearg = lua_tostring(L, -1); /* use the given type name */ else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA) - typearg = "light userdata"; + typearg = "light userdata"; /* special name for messages */ + else + typearg = luaL_typename(L, arg); /* standard name */ msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg); return luaL_argerror(L, arg, msg); } @@ -229,7 +229,7 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { } -#if !defined(inspectstat) /* { */ +#if !defined(l_inspectstat) /* { */ #if defined(LUA_USE_POSIX) @@ -238,13 +238,13 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { /* ** use appropriate macros to interpret 'pclose' return status */ -#define inspectstat(stat,what) \ +#define l_inspectstat(stat,what) \ if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } #else -#define inspectstat(stat,what) /* no op */ +#define l_inspectstat(stat,what) /* no op */ #endif @@ -256,7 +256,7 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) { if (stat == -1) /* error? */ return luaL_fileresult(L, 0, NULL); else { - inspectstat(stat, what); /* interpret result */ + l_inspectstat(stat, what); /* interpret result */ if (*what == 'e' && stat == 0) /* successful termination? */ lua_pushboolean(L, 1); else @@ -335,7 +335,7 @@ LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def, if (strcmp(lst[i], name) == 0) return i; return luaL_argerror(L, arg, - lua_pushfstring(L, "invalid option " LUA_QS, name)); + lua_pushfstring(L, "invalid option '%s'", name)); } @@ -701,22 +701,23 @@ LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { if (!lua_getmetatable(L, obj)) /* no metatable? */ - return 0; - lua_pushstring(L, event); - if (lua_rawget(L, -2) == LUA_TNIL) { /* is metafield nil? */ - lua_pop(L, 2); /* remove metatable and metafield */ - return 0; - } + return LUA_TNIL; else { - lua_remove(L, -2); /* remove only metatable */ - return 1; + int tt; + lua_pushstring(L, event); + tt = lua_rawget(L, -2); + if (tt == LUA_TNIL) /* is metafield nil? */ + lua_pop(L, 2); /* remove metatable and metafield */ + else + lua_remove(L, -2); /* remove only metatable */ + return tt; /* return metafield type */ } } LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { obj = lua_absindex(L, obj); - if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */ return 0; lua_pushvalue(L, obj); lua_call(L, 1, 1); @@ -822,7 +823,7 @@ LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, /* try global variable (and create one if it does not exist) */ lua_pushglobaltable(L); if (luaL_findtable(L, 0, modname, sizehint) != NULL) - luaL_error(L, "name conflict for module " LUA_QS, modname); + luaL_error(L, "name conflict for module '%s'", modname); lua_pushvalue(L, -1); lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ } diff --git a/src/lauxlib.h b/src/lauxlib.h index b5560143..cecceb3f 100644 --- a/src/lauxlib.h +++ b/src/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.125 2014/06/26 17:25:11 roberto Exp $ +** $Id: lauxlib.h,v 1.126 2014/10/01 11:54:56 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -115,10 +115,6 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) -#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) -#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) -#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) -#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) @@ -210,15 +206,21 @@ LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, /* ** {============================================================ -** Compatibility with deprecated unsigned conversions +** Compatibility with deprecated conversions ** ============================================================= */ -#if defined(LUA_COMPAT_APIUNSIGNED) +#if defined(LUA_COMPAT_APIINTCASTS) -#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) +#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) #define luaL_optunsigned(L,a,d) \ ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) + +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + #endif /* }============================================================ */ diff --git a/src/lbaselib.c b/src/lbaselib.c index de1a767f..af04db0d 100644 --- a/src/lbaselib.c +++ b/src/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.293 2014/07/24 19:33:29 roberto Exp $ +** $Id: lbaselib.c,v 1.303 2014/10/17 19:17:55 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -32,8 +32,7 @@ static int luaB_print (lua_State *L) { lua_call(L, 1, 1); s = lua_tolstring(L, -1, &l); /* get result */ if (s == NULL) - return luaL_error(L, - LUA_QL("tostring") " must return a string to " LUA_QL("print")); + return luaL_error(L, "'tostring' must return a string to 'print'"); if (i>1) luai_writestring("\t", 1); luai_writestring(s, l); lua_pop(L, 1); /* pop result */ @@ -78,7 +77,7 @@ static int luaB_tonumber (lua_State *L) { else { size_t l; const char *s = lua_tolstring(L, 1, &l); - if (s != NULL && lua_strtonum(L, s) == l + 1) + if (s != NULL && lua_stringtonumber(L, s) == l + 1) return 1; /* successful conversion to number */ /* else not a number */ } @@ -87,11 +86,11 @@ static int luaB_tonumber (lua_State *L) { size_t l; const char *s; lua_Integer n = 0; /* to avoid warnings */ - int base = luaL_checkint(L, 2); + lua_Integer base = luaL_checkinteger(L, 2); luaL_checktype(L, 1, LUA_TSTRING); /* before 'luaL_checklstring'! */ s = luaL_checklstring(L, 1, &l); luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); - if (b_str2int(s, base, &n) == s + l) { + if (b_str2int(s, (int)base, &n) == s + l) { lua_pushinteger(L, n); return 1; } /* else not a number */ @@ -102,7 +101,7 @@ static int luaB_tonumber (lua_State *L) { static int luaB_error (lua_State *L) { - int level = luaL_optint(L, 2, 1); + int level = (int)luaL_optinteger(L, 2, 1); lua_settop(L, 1); if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ luaL_where(L, level); @@ -129,7 +128,7 @@ static int luaB_setmetatable (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected"); - if (luaL_getmetafield(L, 1, "__metatable")) + if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL) return luaL_error(L, "cannot change a protected metatable"); lua_settop(L, 2); lua_setmetatable(L, 1); @@ -180,7 +179,7 @@ static int luaB_collectgarbage (lua_State *L) { LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, LUA_GCISRUNNING}; int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; - int ex = luaL_optint(L, 2, 0); + int ex = (int)luaL_optinteger(L, 2, 0); int res = lua_gc(L, o, ex); switch (o) { case LUA_GCCOUNT: { @@ -212,7 +211,7 @@ static int luaB_type (lua_State *L) { static int pairsmeta (lua_State *L, const char *method, int iszero, lua_CFunction iter) { - if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ + if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */ luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ lua_pushcfunction(L, iter); /* will return generator, */ lua_pushvalue(L, 1); /* state, */ @@ -248,7 +247,7 @@ static int luaB_pairs (lua_State *L) { ** Traversal function for 'ipairs' for raw tables */ static int ipairsaux_raw (lua_State *L) { - int i = luaL_checkint(L, 2) + 1; + lua_Integer i = luaL_checkinteger(L, 2) + 1; luaL_checktype(L, 1, LUA_TTABLE); lua_pushinteger(L, i); return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2; @@ -259,17 +258,9 @@ static int ipairsaux_raw (lua_State *L) { ** Traversal function for 'ipairs' for tables with metamethods */ static int ipairsaux (lua_State *L) { - int i = luaL_checkint(L, 2) + 1; - if (i > luaL_len(L, 1)) { /* larger than length? */ - lua_pushnil(L); /* end traversal */ - return 1; - } - else { - lua_pushinteger(L, i); - lua_pushinteger(L, i); /* key for indexing table */ - lua_gettable(L, 1); - return 2; - } + lua_Integer i = luaL_checkinteger(L, 2) + 1; + lua_pushinteger(L, i); + return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; } @@ -279,10 +270,8 @@ static int ipairsaux (lua_State *L) { ** that can affect the traversal. */ static int luaB_ipairs (lua_State *L) { - lua_CFunction iter = - (luaL_getmetafield(L, 1, "__len") || - luaL_getmetafield(L, 1, "__index")) - ? ipairsaux : ipairsaux_raw; + lua_CFunction iter = (luaL_getmetafield(L, 1, "__index") != LUA_TNIL) + ? ipairsaux : ipairsaux_raw; #if defined(LUA_COMPAT_IPAIRS) return pairsmeta(L, "__ipairs", 1, iter); #else @@ -380,7 +369,7 @@ static int luaB_load (lua_State *L) { /* }====================================================== */ -static int dofilecont (lua_State *L, int d1, lua_Ctx d2) { +static int dofilecont (lua_State *L, int d1, lua_KContext d2) { (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */ return lua_gettop(L) - 1; } @@ -415,11 +404,11 @@ static int luaB_select (lua_State *L) { return 1; } else { - int i = luaL_checkint(L, 1); + lua_Integer i = luaL_checkinteger(L, 1); if (i < 0) i = n + i; else if (i > n) i = n; luaL_argcheck(L, 1 <= i, 1, "index out of range"); - return n - i; + return n - (int)i; } } @@ -431,14 +420,14 @@ static int luaB_select (lua_State *L) { ** 'extra' values (where 'extra' is exactly the number of items to be ** ignored). */ -static int finishpcall (lua_State *L, int status, lua_Ctx extra) { +static int finishpcall (lua_State *L, int status, lua_KContext extra) { if (status != LUA_OK && status != LUA_YIELD) { /* error? */ lua_pushboolean(L, 0); /* first result (false) */ lua_pushvalue(L, -2); /* error message */ return 2; /* return false, msg */ } else - return lua_gettop(L) - extra; /* return all results */ + return lua_gettop(L) - (int)extra; /* return all results */ } diff --git a/src/lbitlib.c b/src/lbitlib.c index dfec1d31..cca6f402 100644 --- a/src/lbitlib.c +++ b/src/lbitlib.c @@ -1,5 +1,5 @@ /* -** $Id: lbitlib.c,v 1.26 2014/05/15 19:28:34 roberto Exp $ +** $Id: lbitlib.c,v 1.27 2014/10/01 11:54:56 roberto Exp $ ** Standard library for bitwise operations ** See Copyright Notice in lua.h */ @@ -89,7 +89,7 @@ static int b_not (lua_State *L) { } -static int b_shift (lua_State *L, lua_Unsigned r, int i) { +static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) { if (i < 0) { /* shift right? */ i = -i; r = trim(r); @@ -107,18 +107,18 @@ static int b_shift (lua_State *L, lua_Unsigned r, int i) { static int b_lshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); + return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkinteger(L, 2)); } static int b_rshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); + return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkinteger(L, 2)); } static int b_arshift (lua_State *L) { lua_Unsigned r = luaL_checkunsigned(L, 1); - int i = luaL_checkint(L, 2); + lua_Integer i = luaL_checkinteger(L, 2); if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) return b_shift(L, r, -i); else { /* arithmetic shift for 'negative' number */ @@ -131,9 +131,9 @@ static int b_arshift (lua_State *L) { } -static int b_rot (lua_State *L, int i) { +static int b_rot (lua_State *L, lua_Integer d) { lua_Unsigned r = luaL_checkunsigned(L, 1); - i &= (LUA_NBITS - 1); /* i = i % NBITS */ + int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ r = trim(r); if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ r = (r << i) | (r >> (LUA_NBITS - i)); @@ -143,12 +143,12 @@ static int b_rot (lua_State *L, int i) { static int b_lrot (lua_State *L) { - return b_rot(L, luaL_checkint(L, 2)); + return b_rot(L, luaL_checkinteger(L, 2)); } static int b_rrot (lua_State *L) { - return b_rot(L, -luaL_checkint(L, 2)); + return b_rot(L, -luaL_checkinteger(L, 2)); } @@ -159,14 +159,14 @@ static int b_rrot (lua_State *L) { ** 'width' being used uninitialized.) */ static int fieldargs (lua_State *L, int farg, int *width) { - int f = luaL_checkint(L, farg); - int w = luaL_optint(L, farg + 1, 1); + lua_Integer f = luaL_checkinteger(L, farg); + lua_Integer w = luaL_optinteger(L, farg + 1, 1); luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); if (f + w > LUA_NBITS) luaL_error(L, "trying to access non-existent bits"); - *width = w; - return f; + *width = (int)w; + return (int)f; } diff --git a/src/lcorolib.c b/src/lcorolib.c index fae85b95..cb6cfe5a 100644 --- a/src/lcorolib.c +++ b/src/lcorolib.c @@ -1,5 +1,5 @@ /* -** $Id: lcorolib.c,v 1.6 2014/05/08 13:52:20 roberto Exp $ +** $Id: lcorolib.c,v 1.7 2014/09/01 18:00:04 roberto Exp $ ** Coroutine Library ** See Copyright Notice in lua.h */ @@ -19,7 +19,7 @@ static lua_State *getco (lua_State *L) { lua_State *co = lua_tothread(L, 1); - luaL_argcheck(L, co, 1, "coroutine expected"); + luaL_argcheck(L, co, 1, "thread expected"); return co; } diff --git a/src/ldblib.c b/src/ldblib.c index db79de38..3be75b55 100644 --- a/src/ldblib.c +++ b/src/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.139 2014/05/15 19:27:33 roberto Exp $ +** $Id: ldblib.c,v 1.143 2014/10/17 11:07:26 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -21,33 +21,6 @@ #define HOOKKEY "_HKEY" -static int db_Csize (lua_State *L) { - static struct { - char c; - unsigned char sz; - } sizes[] = { - {'I', sizeof(lua_Integer)}, - {'F', sizeof(lua_Number)}, - {'b', CHAR_BIT}, /* here is number of bits (not bytes) */ - {'h', sizeof(short)}, - {'i', sizeof(int)}, - {'l', sizeof(long)}, - {'z', sizeof(size_t)}, - {'f', sizeof(float)}, - {'d', sizeof(double)} - }; - const char *s = luaL_checkstring(L, 1); - int i; - for (i = 0; i < (int)(sizeof(sizes)/sizeof(sizes[0])); i++) { - if (*s == sizes[i].c) { - lua_pushinteger(L, sizes[i].sz); - return 1; - } - } - return luaL_argerror(L, 1, lua_pushfstring(L, "invalid option '%c'", *s)); -} - - static int db_getregistry (lua_State *L) { lua_pushvalue(L, LUA_REGISTRYINDEX); return 1; @@ -160,7 +133,7 @@ static int db_getinfo (lua_State *L) { lua_xmove(L, L1, 1); } else { /* stack level */ - if (!lua_getstack(L1, luaL_checkint(L, arg + 1), &ar)) { + if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { lua_pushnil(L); /* level out of range */ return 1; } @@ -201,14 +174,15 @@ static int db_getlocal (lua_State *L) { lua_State *L1 = getthread(L, &arg); lua_Debug ar; const char *name; - int nvar = luaL_checkint(L, arg+2); /* local-variable index */ + int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */ if (lua_isfunction(L, arg + 1)) { /* function argument? */ lua_pushvalue(L, arg + 1); /* push function */ lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ return 1; /* return only name (there is no value) */ } else { /* stack-level argument */ - if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + int level = (int)luaL_checkinteger(L, arg + 1); + if (!lua_getstack(L1, level, &ar)) /* out of range? */ return luaL_argerror(L, arg+1, "level out of range"); name = lua_getlocal(L1, &ar, nvar); if (name) { @@ -229,12 +203,13 @@ static int db_setlocal (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); lua_Debug ar; - if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + int level = (int)luaL_checkinteger(L, arg + 1); + if (!lua_getstack(L1, level, &ar)) /* out of range? */ return luaL_argerror(L, arg+1, "level out of range"); luaL_checkany(L, arg+3); lua_settop(L, arg+3); lua_xmove(L, L1, 1); - lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); + lua_pushstring(L, lua_setlocal(L1, &ar, (int)luaL_checkinteger(L, arg+2))); return 1; } @@ -244,7 +219,7 @@ static int db_setlocal (lua_State *L) { */ static int auxupvalue (lua_State *L, int get) { const char *name; - int n = luaL_checkint(L, 2); /* upvalue index */ + int n = (int)luaL_checkinteger(L, 2); /* upvalue index */ luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */ name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); if (name == NULL) return 0; @@ -270,7 +245,7 @@ static int db_setupvalue (lua_State *L) { ** returns its index */ static int checkupval (lua_State *L, int argf, int argnup) { - int nup = luaL_checkint(L, argnup); /* upvalue index */ + int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */ luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup, "invalid upvalue index"); @@ -359,7 +334,7 @@ static int db_sethook (lua_State *L) { else { const char *smask = luaL_checkstring(L, arg+2); luaL_checktype(L, arg+1, LUA_TFUNCTION); - count = luaL_optint(L, arg+3, 0); + count = (int)luaL_optinteger(L, arg + 3, 0); func = hookf; mask = makemask(smask, count); } if (gethooktable(L) == 0) { /* creating hook table? */ @@ -418,7 +393,7 @@ static int db_traceback (lua_State *L) { if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ lua_pushvalue(L, arg + 1); /* return it untouched */ else { - int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0); + int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0); luaL_traceback(L, L1, msg, level); } return 1; @@ -426,7 +401,6 @@ static int db_traceback (lua_State *L) { static const luaL_Reg dblib[] = { - {"Csize", db_Csize}, {"debug", db_debug}, {"getuservalue", db_getuservalue}, {"gethook", db_gethook}, diff --git a/src/ldebug.c b/src/ldebug.c index 3321d9f1..cf7d7ca6 100644 --- a/src/ldebug.c +++ b/src/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.100 2014/07/30 14:00:14 roberto Exp $ +** $Id: ldebug.c,v 2.101 2014/10/17 16:28:21 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -515,7 +515,7 @@ static const char *varinfo (lua_State *L, const TValue *o) { kind = getobjname(ci_func(ci)->p, currentpc(ci), cast_int(o - ci->u.l.base), &name); } - return (kind) ? luaO_pushfstring(L, " (%s " LUA_QS ")", kind, name) : ""; + return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; } @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.126 2014/07/17 13:53:37 roberto Exp $ +** $Id: ldo.c,v 2.130 2014/10/17 16:28:21 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -111,15 +111,16 @@ l_noret luaD_throw (lua_State *L, int errcode) { LUAI_THROW(L, L->errorJmp); /* jump to it */ } else { /* thread has no error handler */ + global_State *g = G(L); L->status = cast_byte(errcode); /* mark it as dead */ - if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */ - setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */ - luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */ + if (g->mainthread->errorJmp) { /* main thread has a handler? */ + setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ + luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ } else { /* no handler at all; abort */ - if (G(L)->panic) { /* panic function? */ + if (g->panic) { /* panic function? */ lua_unlock(L); - G(L)->panic(L); /* call it (last chance to jump out) */ + g->panic(L); /* call it (last chance to jump out) */ } abort(); } @@ -593,7 +594,7 @@ LUA_API int lua_isyieldable (lua_State *L) { } -LUA_API int lua_yieldk (lua_State *L, int nresults, lua_Ctx ctx, +LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k) { CallInfo *ci = L->ci; luai_userstateyield(L, nresults); @@ -661,7 +662,7 @@ struct SParser { /* data to `f_parser' */ static void checkmode (lua_State *L, const char *mode, const char *x) { if (mode && strchr(mode, x[0]) == NULL) { luaO_pushfstring(L, - "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); + "attempt to load a %s chunk (mode is '%s')", x, mode); luaD_throw(L, LUA_ERRSYNTAX); } } @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.192 2014/07/29 16:22:24 roberto Exp $ +** $Id: lgc.c,v 2.196 2014/10/03 12:54:37 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -100,9 +100,9 @@ static void reallymarkobject (global_State *g, GCObject *o); /* -** link table 'h' into list pointed by 'p' +** link collectable object 'o' into list pointed by 'p' */ -#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h)) +#define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o)) /* @@ -159,8 +159,7 @@ void luaC_barrierback_ (lua_State *L, Table *t) { global_State *g = G(L); lua_assert(isblack(t) && !isdead(g, t)); black2gray(t); /* make table gray (again) */ - t->gclist = g->grayagain; - g->grayagain = obj2gco(t); + linkgclist(t, g->grayagain); } @@ -243,27 +242,23 @@ static void reallymarkobject (global_State *g, GCObject *o) { break; } case LUA_TLCL: { - gco2lcl(o)->gclist = g->gray; - g->gray = o; + linkgclist(gco2lcl(o), g->gray); break; } case LUA_TCCL: { - gco2ccl(o)->gclist = g->gray; - g->gray = o; + linkgclist(gco2ccl(o), g->gray); break; } case LUA_TTABLE: { - linktable(gco2t(o), &g->gray); + linkgclist(gco2t(o), g->gray); break; } case LUA_TTHREAD: { - gco2th(o)->gclist = g->gray; - g->gray = o; + linkgclist(gco2th(o), g->gray); break; } case LUA_TPROTO: { - gco2p(o)->gclist = g->gray; - g->gray = o; + linkgclist(gco2p(o), g->gray); break; } default: lua_assert(0); break; @@ -340,12 +335,18 @@ static void restartcollection (global_State *g) { ** ======================================================= */ +/* +** Traverse a table with weak values and link it to proper list. During +** propagate phase, keep it in 'grayagain' list, to be revisited in the +** atomic phase. In the atomic phase, if table has any white value, +** put it in 'weak' list, to be cleared. +*/ static void traverseweakvalue (global_State *g, Table *h) { Node *n, *limit = gnodelast(h); - /* if there is array part, assume it may have white values (do not - traverse it just to check) */ + /* if there is array part, assume it may have white values (it is not + worth traversing it now just to check) */ int hasclears = (h->sizearray > 0); - for (n = gnode(h, 0); n < limit; n++) { + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ checkdeadkey(n); if (ttisnil(gval(n))) /* entry is empty? */ removeentry(n); /* remove it */ @@ -356,20 +357,30 @@ static void traverseweakvalue (global_State *g, Table *h) { hasclears = 1; /* table will have to be cleared */ } } - if (hasclears) - linktable(h, &g->weak); /* has to be cleared later */ - else /* no white values */ - linktable(h, &g->grayagain); /* no need to clean */ + if (g->gcstate == GCSpropagate) + linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ + else if (hasclears) + linkgclist(h, g->weak); /* has to be cleared later */ } +/* +** Traverse an ephemeron table and link it to proper list. Returns true +** iff any object was marked during this traversal (which implies that +** convergence has to continue). During propagation phase, keep table +** in 'grayagain' list, to be visited again in the atomic phase. In +** the atomic phase, if table has any white->white entry, it has to +** be revisited during ephemeron convergence (as that key may turn +** black). Otherwise, if it has any white key, table has to be cleared +** (in the atomic phase). +*/ static int traverseephemeron (global_State *g, Table *h) { int marked = 0; /* true if an object is marked in this traversal */ int hasclears = 0; /* true if table has white keys */ - int prop = 0; /* true if table has entry "white-key -> white-value" */ + int hasww = 0; /* true if table has entry "white-key -> white-value" */ Node *n, *limit = gnodelast(h); - int i; - /* traverse array part (numeric keys are 'strong') */ + unsigned int i; + /* traverse array part */ for (i = 0; i < h->sizearray; i++) { if (valiswhite(&h->array[i])) { marked = 1; @@ -384,26 +395,27 @@ static int traverseephemeron (global_State *g, Table *h) { else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */ hasclears = 1; /* table must be cleared */ if (valiswhite(gval(n))) /* value not marked yet? */ - prop = 1; /* must propagate again */ + hasww = 1; /* white-white entry */ } else if (valiswhite(gval(n))) { /* value not marked yet? */ marked = 1; reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ } } - if (prop) - linktable(h, &g->ephemeron); /* have to propagate again */ - else if (hasclears) /* does table have white keys? */ - linktable(h, &g->allweak); /* may have to clean white keys */ - else /* no white keys */ - linktable(h, &g->grayagain); /* no need to clean */ + /* link table into proper list */ + if (g->gcstate == GCSpropagate) + linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ + else if (hasww) /* table has white->white entries? */ + linkgclist(h, g->ephemeron); /* have to propagate again */ + else if (hasclears) /* table has white keys? */ + linkgclist(h, g->allweak); /* may have to clean white keys */ return marked; } static void traversestrongtable (global_State *g, Table *h) { Node *n, *limit = gnodelast(h); - int i; + unsigned int i; for (i = 0; i < h->sizearray; i++) /* traverse array part */ markvalue(g, &h->array[i]); for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ @@ -433,7 +445,7 @@ static lu_mem traversetable (global_State *g, Table *h) { else if (!weakvalue) /* strong values? */ traverseephemeron(g, h); else /* all weak */ - linktable(h, &g->allweak); /* nothing to traverse now */ + linkgclist(h, g->allweak); /* nothing to traverse now */ } else /* not weak */ traversestrongtable(g, h); @@ -548,8 +560,7 @@ static void propagatemark (global_State *g) { case LUA_TTHREAD: { lua_State *th = gco2th(o); g->gray = th->gclist; /* remove from 'gray' list */ - th->gclist = g->grayagain; - g->grayagain = o; /* insert into 'grayagain' list */ + linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ black2gray(o); size = traversethread(g, th); break; @@ -571,35 +582,12 @@ static void propagateall (global_State *g) { } -static void propagatelist (global_State *g, GCObject *l) { - lua_assert(g->gray == NULL); /* no grays left */ - g->gray = l; - propagateall(g); /* traverse all elements from 'l' */ -} - -/* -** retraverse all gray lists. Because tables may be reinserted in other -** lists when traversed, traverse the original lists to avoid traversing -** twice the same table (which is not wrong, but inefficient) -*/ -static void retraversegrays (global_State *g) { - GCObject *weak = g->weak; /* save original lists */ - GCObject *grayagain = g->grayagain; - GCObject *ephemeron = g->ephemeron; - g->weak = g->grayagain = g->ephemeron = NULL; - propagateall(g); /* traverse main gray list */ - propagatelist(g, grayagain); - propagatelist(g, weak); - propagatelist(g, ephemeron); -} - - static void convergeephemerons (global_State *g) { int changed; do { GCObject *w; GCObject *next = g->ephemeron; /* get ephemeron list */ - g->ephemeron = NULL; /* tables will return to this list when traversed */ + g->ephemeron = NULL; /* tables may return to this list when traversed */ changed = 0; while ((w = next) != NULL) { next = gco2t(w)->gclist; @@ -647,7 +635,7 @@ static void clearvalues (global_State *g, GCObject *l, GCObject *f) { for (; l != f; l = gco2t(l)->gclist) { Table *h = gco2t(l); Node *n, *limit = gnodelast(h); - int i; + unsigned int i; for (i = 0; i < h->sizearray; i++) { TValue *o = &h->array[i]; if (iscleared(g, o)) /* value was collected? */ @@ -864,7 +852,7 @@ static GCObject **findlast (GCObject **p) { /* ** move all unreachable objects (or 'all' objects) that need -** finalization from list 'p' to list 'tobefnz' (to be finalized) +** finalization from list 'finobj' to list 'tobefnz' (to be finalized) */ static void separatetobefnz (global_State *g, int all) { GCObject *curr; @@ -875,7 +863,7 @@ static void separatetobefnz (global_State *g, int all) { if (!(iswhite(curr) || all)) /* not being collected? */ p = &curr->next; /* don't bother with it */ else { - *p = curr->next; /* remove 'curr' from "fin" list */ + *p = curr->next; /* remove 'curr' from 'finobj' list */ curr->next = *lastnext; /* link at the end of 'tobefnz' list */ *lastnext = curr; lastnext = &curr->next; @@ -903,7 +891,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { /* search for pointer pointing to 'o' */ for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } *p = o->next; /* remove 'o' from 'allgc' list */ - o->next = g->finobj; /* link it in "fin" list */ + o->next = g->finobj; /* link it in 'finobj' list */ g->finobj = o; l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ } @@ -972,19 +960,21 @@ static l_mem atomic (lua_State *L) { global_State *g = G(L); l_mem work; GCObject *origweak, *origall; - g->GCmemtrav = 0; /* start counting work */ + GCObject *grayagain = g->grayagain; /* save original list */ + lua_assert(g->ephemeron == NULL && g->weak == NULL); lua_assert(!iswhite(g->mainthread)); g->gcstate = GCSinsideatomic; + g->GCmemtrav = 0; /* start counting work */ markobject(g, L); /* mark running thread */ /* registry and global metatables may be changed by API */ markvalue(g, &g->l_registry); - markmt(g); /* mark basic metatables */ + markmt(g); /* mark global metatables */ /* remark occasional upvalues of (maybe) dead threads */ remarkupvals(g); propagateall(g); /* propagate changes */ - work = g->GCmemtrav; /* stop counting (do not (re)count grays) */ - /* traverse objects caught by write barrier and by 'remarkupvals' */ - retraversegrays(g); + work = g->GCmemtrav; /* stop counting (do not recount gray-agains) */ + g->gray = grayagain; + propagateall(g); /* traverse 'grayagain' list */ g->GCmemtrav = 0; /* restart counting */ convergeephemerons(g); /* at this point, all strongly accessible objects are marked. */ diff --git a/src/liolib.c b/src/liolib.c index 96cb1a31..9101ecae 100644 --- a/src/liolib.c +++ b/src/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.128 2014/07/29 16:01:00 roberto Exp $ +** $Id: liolib.c,v 2.136 2014/10/22 16:55:57 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -70,7 +70,7 @@ /* ANSI definitions */ #define l_popen(L,c,m) \ ((void)((void)c, m), \ - luaL_error(L, LUA_QL("popen") " not supported"), \ + luaL_error(L, "'popen' not supported"), \ (FILE*)0) #define l_pclose(L,file) ((void)L, (void)file, -1) @@ -135,6 +135,7 @@ #define IO_PREFIX "_IO_" +#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1) #define IO_INPUT (IO_PREFIX "input") #define IO_OUTPUT (IO_PREFIX "output") @@ -193,9 +194,14 @@ static LStream *newprefile (lua_State *L) { } +/* +** Calls the 'close' function from a file handle. The 'volatile' avoids +** a bug in some versions of the Clang compiler (e.g., clang 3.0 for +** 32 bits). +*/ static int aux_close (lua_State *L) { LStream *p = tolstream(L); - lua_CFunction cf = p->closef; + volatile lua_CFunction cf = p->closef; p->closef = NULL; /* mark stream as closed */ return (*cf)(L); /* close it */ } @@ -239,7 +245,7 @@ static void opencheck (lua_State *L, const char *fname, const char *mode) { LStream *p = newfile(L); p->f = fopen(fname, mode); if (p->f == NULL) - luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno)); + luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno)); } @@ -285,7 +291,7 @@ static FILE *getiofile (lua_State *L, const char *findex) { lua_getfield(L, LUA_REGISTRYINDEX, findex); p = (LStream *)lua_touserdata(L, -1); if (isclosed(p)) - luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX)); + luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN); return p->f; } @@ -413,15 +419,15 @@ static int readdigits (RN *rn, int hex) { /* access to locale "radix character" (decimal point) */ -#if !defined(getlocaledecpoint) -#define getlocaledecpoint() (localeconv()->decimal_point[0]) +#if !defined(l_getlocaledecpoint) +#define l_getlocaledecpoint() (localeconv()->decimal_point[0]) #endif /* ** Read a number: first reads a valid prefix of a numeral into a buffer. -** Then it calls 'lua_strtonum' to check whether the format is correct -** and to convert it to a Lua number +** Then it calls 'lua_stringtonumber' to check whether the format is +** correct and to convert it to a Lua number */ static int read_number (lua_State *L, FILE *f) { RN rn; @@ -429,7 +435,7 @@ static int read_number (lua_State *L, FILE *f) { int hex = 0; char decp[2] = "."; rn.f = f; rn.n = 0; - decp[0] = getlocaledecpoint(); /* get decimal point from locale */ + decp[0] = l_getlocaledecpoint(); /* get decimal point from locale */ l_lockfile(rn.f); do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ test2(&rn, "-+"); /* optional signal */ @@ -447,7 +453,7 @@ static int read_number (lua_State *L, FILE *f) { ungetc(rn.c, rn.f); /* unread look-ahead char */ l_unlockfile(rn.f); rn.buff[rn.n] = '\0'; /* finish string */ - if (lua_strtonum(L, rn.buff)) /* is this a valid number? */ + if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */ return 1; /* ok */ else { /* invalid format */ lua_pushnil(L); /* "result" to be removed */ @@ -576,7 +582,7 @@ 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 */ if (n > 1) { /* is there error information? */ @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.80 2014/07/18 13:36:14 roberto Exp $ +** $Id: llex.c,v 2.84 2014/10/22 11:44:20 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -78,14 +78,13 @@ void luaX_init (lua_State *L) { const char *luaX_token2str (LexState *ls, int token) { if (token < FIRST_RESERVED) { /* single-byte symbols? */ - lua_assert(token == cast(unsigned char, token)); - return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) : - luaO_pushfstring(ls->L, "char(%d)", token); + lua_assert(token == cast_uchar(token)); + return luaO_pushfstring(ls->L, "'%c'", token); } else { const char *s = luaX_tokens[token - FIRST_RESERVED]; if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ - return luaO_pushfstring(ls->L, LUA_QS, s); + return luaO_pushfstring(ls->L, "'%s'", s); else /* names, strings, and numerals */ return s; } @@ -97,7 +96,7 @@ static const char *txtToken (LexState *ls, int token) { case TK_NAME: case TK_STRING: case TK_FLT: case TK_INT: save(ls, '\0'); - return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff)); + return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff)); default: return luaX_token2str(ls, token); } @@ -219,8 +218,8 @@ static void buffreplace (LexState *ls, char from, char to) { } -#if !defined(getlocaledecpoint) -#define getlocaledecpoint() (localeconv()->decimal_point[0]) +#if !defined(l_getlocaledecpoint) +#define l_getlocaledecpoint() (localeconv()->decimal_point[0]) #endif @@ -232,7 +231,7 @@ static void buffreplace (LexState *ls, char from, char to) { */ static void trydecpoint (LexState *ls, TValue *o) { char old = ls->decpoint; - ls->decpoint = getlocaledecpoint(); + ls->decpoint = l_getlocaledecpoint(); buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ if (!buff2num(ls->buff, o)) { /* format error with correct decimal point: no more options */ @@ -360,8 +359,8 @@ static int readhexaesc (LexState *ls) { } -static unsigned int readutf8esc (LexState *ls) { - unsigned int r; +static unsigned long readutf8esc (LexState *ls) { + unsigned long r; int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */ save_and_next(ls); /* skip 'u' */ esccheck(ls, ls->current == '{', "missing '{'"); diff --git a/src/lmathlib.c b/src/lmathlib.c index 312df517..523e0b64 100644 --- a/src/lmathlib.c +++ b/src/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.108 2014/07/28 17:35:47 roberto Exp $ +** $Id: lmathlib.c,v 1.110 2014/10/08 19:57:31 roberto Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -153,7 +153,7 @@ static int math_modf (lua_State *L) { lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); pushnumint(L, ip); /* fractional part (test needed for inf/-inf) */ - lua_pushnumber(L, (n == ip) ? 0.0 : (n - ip)); + lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); } return 2; } @@ -192,12 +192,12 @@ static int math_exp (lua_State *L) { } static int math_deg (lua_State *L) { - lua_pushnumber(L, luaL_checknumber(L, 1) * (180.0 / PI)); + lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); return 1; } static int math_rad (lua_State *L) { - lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / 180.0)); + lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); return 1; } @@ -239,7 +239,7 @@ static int math_random (lua_State *L) { double r = (double)l_rand() * (1.0 / ((double)RAND_MAX + 1.0)); switch (lua_gettop(L)) { /* check number of arguments */ case 0: { /* no arguments */ - lua_pushnumber(L, r); /* Number between 0 and 1 */ + lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */ return 1; } case 1: { /* only upper limit */ @@ -324,7 +324,7 @@ static int math_frexp (lua_State *L) { static int math_ldexp (lua_State *L) { lua_Number x = luaL_checknumber(L, 1); - int ep = luaL_checkint(L, 2); + int ep = (int)luaL_checkinteger(L, 2); lua_pushnumber(L, l_mathop(ldexp)(x, ep)); return 1; } @@ -389,7 +389,7 @@ LUAMOD_API int luaopen_math (lua_State *L) { luaL_newlib(L, mathlib); lua_pushnumber(L, PI); lua_setfield(L, -2, "pi"); - lua_pushnumber(L, HUGE_VAL); + lua_pushnumber(L, (lua_Number)HUGE_VAL); lua_setfield(L, -2, "huge"); lua_pushinteger(L, LUA_MAXINTEGER); lua_setfield(L, -2, "maxinteger"); @@ -1,5 +1,5 @@ /* -** $Id: lmem.h,v 1.40 2013/02/20 14:08:21 roberto Exp $ +** $Id: lmem.h,v 1.41 2014/10/08 20:25:51 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -15,20 +15,26 @@ /* -** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is -** always constant. -** The macro is somewhat complex to avoid warnings: -** +1 avoids warnings of "comparison has constant result"; -** cast to 'void' avoids warnings of "value unused". +** This macro reallocs a vector 'b' from 'on' to 'n' elements, where +** each element has size 'e'. In case of arithmetic overflow of the +** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because +** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e). +** +** (The macro is somewhat complex to avoid warnings: The 'sizeof' +** comparison avoids a runtime comparison when overflow cannot occur. +** The compiler should be able to optimize the real test by itself, but +** when it does it, it may give a warning about "comparison is always +** false due to limited range of data type"; the +1 tricks the compiler, +** avoiding this warning but also this optimization.) */ #define luaM_reallocv(L,b,on,n,e) \ - (cast(void, \ - (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \ + (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \ + ? luaM_toobig(L) : cast_void(0)) , \ luaM_realloc_(L, (b), (on)*(e), (n)*(e))) #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) -#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0])) +#define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0) #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) diff --git a/src/loadlib.c b/src/loadlib.c index 4894188a..9cf5e69d 100644 --- a/src/loadlib.c +++ b/src/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.116 2014/07/29 16:01:00 roberto Exp $ +** $Id: loadlib.c,v 1.117 2014/10/17 16:28:21 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** @@ -396,7 +396,7 @@ static const char *searchpath (lua_State *L, const char *name, lua_remove(L, -2); /* remove path template */ if (readable(filename)) /* does file exist and is readable? */ return filename; /* return that file name */ - lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_pushfstring(L, "\n\tno file '%s'", filename); lua_remove(L, -2); /* remove file name */ luaL_addvalue(&msg); /* concatenate error msg. entry */ } @@ -426,7 +426,7 @@ static const char *findfile (lua_State *L, const char *name, lua_getfield(L, lua_upvalueindex(1), pname); path = lua_tostring(L, -1); if (path == NULL) - luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + luaL_error(L, "'package.%s' must be a string", pname); return searchpath(L, name, path, ".", dirsep); } @@ -437,8 +437,7 @@ static int checkload (lua_State *L, int stat, const char *filename) { return 2; /* return open function and file name */ } else - return luaL_error(L, "error loading module " LUA_QS - " from file " LUA_QS ":\n\t%s", + return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s", lua_tostring(L, 1), filename, lua_tostring(L, -1)); } @@ -499,8 +498,7 @@ static int searcher_Croot (lua_State *L) { if (stat != ERRFUNC) return checkload(L, 0, filename); /* real error */ else { /* open function not found */ - lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, - name, filename); + lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename); return 1; } } @@ -524,14 +522,13 @@ static void findloader (lua_State *L, const char *name) { luaL_buffinit(L, &msg); lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ if (!lua_istable(L, 3)) - luaL_error(L, LUA_QL("package.searchers") " must be a table"); + luaL_error(L, "'package.searchers' must be a table"); /* iterate over available searchers to find a loader */ for (i = 1; ; i++) { if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */ lua_pop(L, 1); /* remove nil */ luaL_pushresult(&msg); /* create error message */ - luaL_error(L, "module " LUA_QS " not found:%s", - name, lua_tostring(L, -1)); + luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1)); } lua_pushstring(L, name); lua_call(L, 1, 2); /* call it */ @@ -589,7 +586,7 @@ static void set_env (lua_State *L) { if (lua_getstack(L, 1, &ar) == 0 || lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ lua_iscfunction(L, -1)) - luaL_error(L, LUA_QL("module") " not called from a Lua function"); + luaL_error(L, "'module' not called from a Lua function"); lua_pushvalue(L, -2); /* copy new environment table to top */ lua_setupvalue(L, -2, 1); lua_pop(L, 1); /* remove function */ diff --git a/src/lobject.c b/src/lobject.c index 2bcdbfa1..28048dd7 100644 --- a/src/lobject.c +++ b/src/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 2.88 2014/07/30 14:00:14 roberto Exp $ +** $Id: lobject.c,v 2.93 2014/10/17 16:28:21 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -310,10 +310,11 @@ size_t luaO_str2num (const char *s, TValue *o) { } -int luaO_utf8esc (char *buff, unsigned int x) { +int luaO_utf8esc (char *buff, unsigned long x) { int n = 1; /* number of bytes put in buffer (backwards) */ + lua_assert(x <= 0x10FFFF); if (x < 0x80) /* ascii? */ - buff[UTF8BUFFSZ - 1] = x; + buff[UTF8BUFFSZ - 1] = cast(char, x); else { /* need continuation bytes */ unsigned int mfb = 0x3f; /* maximum that fits in first byte */ do { @@ -321,7 +322,7 @@ int luaO_utf8esc (char *buff, unsigned int x) { x >>= 6; /* remove added bits */ mfb >>= 1; /* now there is one less bit available in first byte */ } while (x > mfb); /* still needs continuation byte? */ - buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */ + buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */ } return n; } @@ -359,7 +360,7 @@ static void pushstr (lua_State *L, const char *str, size_t l) { /* this function handles only '%d', '%c', '%f', '%p', and '%s' - conventional formats, plus Lua-specific '%L' and '%U' */ + conventional formats, plus Lua-specific '%I' and '%U' */ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { int n = 0; for (;;) { @@ -376,7 +377,10 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { } case 'c': { char buff = cast(char, va_arg(argp, int)); - pushstr(L, &buff, 1); + if (lisprint(cast_uchar(buff))) + pushstr(L, &buff, 1); + else /* non-printable character; print its code */ + luaO_pushfstring(L, "<\\%d>", cast_uchar(buff)); break; } case 'd': { @@ -402,7 +406,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { } case 'U': { char buff[UTF8BUFFSZ]; - int l = luaO_utf8esc(buff, va_arg(argp, int)); + int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long))); pushstr(L, buff + UTF8BUFFSZ - l, l); break; } @@ -411,9 +415,8 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { break; } default: { - luaG_runerror(L, - "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"), - *(e + 1)); + luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'", + *(e + 1)); } } n += 2; diff --git a/src/lobject.h b/src/lobject.h index 9972e08b..054df783 100644 --- a/src/lobject.h +++ b/src/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.101 2014/07/30 14:00:14 roberto Exp $ +** $Id: lobject.h,v 2.103 2014/10/01 11:52:33 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -487,7 +487,7 @@ typedef struct Table { CommonHeader; lu_byte flags; /* 1<<p means tagmethod(p) is not present */ lu_byte lsizenode; /* log2 of size of `node' array */ - int sizearray; /* size of `array' array */ + unsigned int sizearray; /* size of `array' array */ TValue *array; /* array part */ Node *node; Node *lastfree; /* any free position is before this position */ @@ -521,7 +521,7 @@ LUAI_DDEC const TValue luaO_nilobject_; LUAI_FUNC int luaO_int2fb (unsigned int x); LUAI_FUNC int luaO_fb2int (int x); -LUAI_FUNC int luaO_utf8esc (char *buff, unsigned int x); +LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); LUAI_FUNC int luaO_ceillog2 (unsigned int x); LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, TValue *res); diff --git a/src/lopcodes.h b/src/lopcodes.h index 3f5d0153..eb6c2a0d 100644 --- a/src/lopcodes.h +++ b/src/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.146 2013/12/30 20:47:58 roberto Exp $ +** $Id: lopcodes.h,v 1.147 2014/10/20 18:29:55 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -203,7 +203,7 @@ OP_LEN,/* A B R(A) := length of R(B) */ OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ -OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */ +OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */ OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ diff --git a/src/loslib.c b/src/loslib.c index 3be1d999..c721e711 100644 --- a/src/loslib.c +++ b/src/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.46 2014/04/29 17:05:13 roberto Exp $ +** $Id: loslib.c,v 1.49 2014/10/17 16:28:21 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -189,7 +189,7 @@ static int getfield (lua_State *L, const char *key, int d) { res = (int)lua_tointegerx(L, -1, &isnum); if (!isnum) { if (d < 0) - return luaL_error(L, "field " LUA_QS " missing in date table", key); + return luaL_error(L, "field '%s' missing in date table", key); res = d; } lua_pop(L, 1); @@ -295,7 +295,8 @@ static int os_time (lua_State *L) { static int os_difftime (lua_State *L) { - lua_pushnumber(L, difftime((l_checktime(L, 1)), (l_checktime(L, 2)))); + double res = difftime((l_checktime(L, 1)), (l_checktime(L, 2))); + lua_pushnumber(L, (lua_Number)res); return 1; } @@ -319,7 +320,7 @@ static int os_exit (lua_State *L) { if (lua_isboolean(L, 1)) status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); else - status = luaL_optint(L, 1, EXIT_SUCCESS); + status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS); if (lua_toboolean(L, 2)) lua_close(L); if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ diff --git a/src/lparser.c b/src/lparser.c index 1e7e244a..2c009658 100644 --- a/src/lparser.c +++ b/src/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.142 2014/07/21 16:02:10 roberto Exp $ +** $Id: lparser.c,v 2.143 2014/10/17 16:28:21 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -340,7 +340,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) { if (gt->nactvar < label->nactvar) { TString *vname = getlocvar(fs, gt->nactvar)->varname; const char *msg = luaO_pushfstring(ls->L, - "<goto %s> at line %d jumps into the scope of local " LUA_QS, + "<goto %s> at line %d jumps into the scope of local '%s'", getstr(gt->name), gt->line, getstr(vname)); semerror(ls, msg); } @@ -457,7 +457,7 @@ static void breaklabel (LexState *ls) { static l_noret undefgoto (LexState *ls, Labeldesc *gt) { const char *msg = isreserved(gt->name) ? "<%s> at line %d not inside a loop" - : "no visible label " LUA_QS " for <goto> at line %d"; + : "no visible label '%s' for <goto> at line %d"; msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); semerror(ls, msg); } @@ -761,7 +761,7 @@ static void parlist (LexState *ls) { f->is_vararg = 1; break; } - default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected"); + default: luaX_syntaxerror(ls, "<name> or '...' expected"); } } while (!f->is_vararg && testnext(ls, ',')); } @@ -953,7 +953,7 @@ static void simpleexp (LexState *ls, expdesc *v) { case TK_DOTS: { /* vararg */ FuncState *fs = ls->fs; check_condition(ls, fs->f->is_vararg, - "cannot use " LUA_QL("...") " outside a vararg function"); + "cannot use '...' outside a vararg function"); init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); break; } @@ -1200,7 +1200,7 @@ static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { for (i = fs->bl->firstlabel; i < ll->n; i++) { if (eqstr(label, ll->arr[i].name)) { const char *msg = luaO_pushfstring(fs->ls->L, - "label " LUA_QS " already defined on line %d", + "label '%s' already defined on line %d", getstr(label), ll->arr[i].line); semerror(fs->ls, msg); } @@ -1367,7 +1367,7 @@ static void forstat (LexState *ls, int line) { switch (ls->t.token) { case '=': fornum(ls, varname, line); break; case ',': case TK_IN: forlist(ls, varname); break; - default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); + default: luaX_syntaxerror(ls, "'=' or 'in' expected"); } check_match(ls, TK_END, TK_FOR, line); leaveblock(fs); /* loop scope (`break' jumps to this point) */ diff --git a/src/lstate.h b/src/lstate.h index 698bea0d..3ecd4977 100644 --- a/src/lstate.h +++ b/src/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.114 2014/07/23 17:15:43 roberto Exp $ +** $Id: lstate.h,v 2.117 2014/10/07 18:29:13 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -54,7 +54,13 @@ typedef struct stringtable { /* -** information about a call +** Information about a call. +** When a thread yields, 'func' is adjusted to pretend that the +** top function has only the yielded values in its stack; in that +** case, the actual 'func' value is saved in field 'extra'. +** When a function calls another with a continuation, 'extra' keeps +** the function index so that, in case of errors, the continuation +** function can be called with the correct top. */ typedef struct CallInfo { StkId func; /* function index in the stack */ @@ -68,7 +74,7 @@ typedef struct CallInfo { struct { /* only for C functions */ lua_KFunction k; /* continuation in case of yields */ ptrdiff_t old_errfunc; - lua_Ctx ctx; /* context info. in case of yields */ + lua_KContext ctx; /* context info. in case of yields */ } c; } u; ptrdiff_t extra; diff --git a/src/lstrlib.c b/src/lstrlib.c index 05330c80..748e2a81 100644 --- a/src/lstrlib.c +++ b/src/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.200 2014/07/30 13:59:24 roberto Exp $ +** $Id: lstrlib.c,v 1.205 2014/10/20 16:44:54 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -250,14 +250,14 @@ static const char *classend (MatchState *ms, const char *p) { switch (*p++) { case L_ESC: { if (p == ms->p_end) - luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + luaL_error(ms->L, "malformed pattern (ends with '%%')"); return p+1; } case '[': { if (*p == '^') p++; do { /* look for a `]' */ if (p == ms->p_end) - luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + luaL_error(ms->L, "malformed pattern (missing ']')"); if (*(p++) == L_ESC && p < ms->p_end) p++; /* skip escapes (e.g. `%]') */ } while (*p != ']'); @@ -332,8 +332,7 @@ static int singlematch (MatchState *ms, const char *s, const char *p, static const char *matchbalance (MatchState *ms, const char *s, const char *p) { if (p >= ms->p_end - 1) - luaL_error(ms->L, "malformed pattern " - "(missing arguments to " LUA_QL("%%b") ")"); + luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); if (*s != *p) return NULL; else { int b = *p; @@ -450,8 +449,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) { const char *ep; char previous; p += 2; if (*p != '[') - luaL_error(ms->L, "missing " LUA_QL("[") " after " - LUA_QL("%%f") " in pattern"); + luaL_error(ms->L, "missing '[' after '%%f' in pattern"); ep = classend(ms, p); /* points to what is next */ previous = (s == ms->src_init) ? '\0' : *(s - 1); if (!matchbracketclass(uchar(previous), p, ep - 1) && @@ -694,8 +692,7 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, i++; /* skip ESC */ if (!isdigit(uchar(news[i]))) { if (news[i] != L_ESC) - luaL_error(L, "invalid use of " LUA_QL("%c") - " in replacement string", L_ESC); + luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); luaL_addchar(b, news[i]); } else if (news[i] == '0') @@ -890,7 +887,7 @@ static int str_format (lua_State *L) { strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { - nb = sprintf(buff, form, luaL_checkint(L, arg)); + nb = sprintf(buff, form, (int)luaL_checkinteger(L, arg)); break; } case 'd': case 'i': @@ -929,8 +926,8 @@ static int str_format (lua_State *L) { } } default: { /* also treat cases `pnLlh' */ - return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " - LUA_QL("format"), *(strfrmt - 1)); + return luaL_error(L, "invalid option '%%%c' to 'format'", + *(strfrmt - 1)); } } luaL_addsize(&b, nb); @@ -950,212 +947,394 @@ static int str_format (lua_State *L) { */ +/* maximum size for the binary representation of an integer */ +#define MAXINTSIZE 16 + /* number of bits in a character */ #define NB CHAR_BIT /* mask for one character (NB 1's) */ #define MC ((1 << NB) - 1) -/* mask for one character without sign bit ((NB - 1) 1's) */ -#define SM (MC >> 1) - /* size of a lua_Integer */ #define SZINT ((int)sizeof(lua_Integer)) -/* maximum size for the binary representation of an integer */ -#define MAXINTSIZE 12 +/* mask for all ones in last byte in a lua Integer */ +#define HIGHERBYTE ((lua_Unsigned)MC << (NB * (SZINT - 1))) -static union { +/* dummy union to get native endianness */ +static const union { int dummy; char little; /* true iff machine is little endian */ -} const nativeendian = {1}; +} nativeendian = {1}; -static int getendian (lua_State *L, int arg) { - const char *endian = luaL_optstring(L, arg, - (nativeendian.little ? "l" : "b")); - if (*endian == 'n') /* native? */ - return nativeendian.little; - luaL_argcheck(L, *endian == 'l' || *endian == 'b', arg, - "endianness must be 'l'/'b'/'n'"); - return (*endian == 'l'); -} +/* dummy structure to get native alignment requirements */ +struct cD { + char c; + union { double d; void *p; lua_Integer i; lua_Number n; } u; +}; +#define MAXALIGN (offsetof(struct cD, u)) -static int getintsize (lua_State *L, int arg) { - int size = luaL_optint(L, arg, 0); - if (size == 0) size = SZINT; - luaL_argcheck(L, 1 <= size && size <= MAXINTSIZE, arg, - "integer size out of valid range"); - return size; -} +/* +** Union for serializing floats +*/ +typedef union Ftypes { + float f; + double d; + lua_Number n; + char buff[5 * sizeof(lua_Number)]; /* enough for any float type */ +} Ftypes; -/* mask for all ones in last byte in a lua Integer */ -#define HIGHERBYTE ((lua_Unsigned)MC << (NB * (SZINT - 1))) +/* +** information to pack/unpack stuff +*/ +typedef struct Header { + lua_State *L; + int islittle; + int maxalign; +} Header; -static int dumpint (char *buff, lua_Integer m, int littleendian, int size) { - int i; - lua_Unsigned n = (lua_Unsigned)m; - lua_Unsigned mask = (m >= 0) ? 0 : HIGHERBYTE; /* sign extension */ - if (littleendian) { - for (i = 0; i < size - 1; i++) { - buff[i] = (n & MC); - n = (n >> NB) | mask; - } - } + +/* +** options for pack/unpack +*/ +typedef enum KOption { + Kint, /* signed integers */ + Kuint, /* unsigned integers */ + Kfloat, /* floating-point numbers */ + Kchar, /* fixed-length strings */ + Kstring, /* strings with prefixed length */ + Kzstr, /* zero-terminated strings */ + Kpadding, /* padding */ + Kpaddalign, /* padding for alignment */ + Knop, /* no-op (configuration or spaces) */ + Keof /* end of format */ +} KOption; + + +/* +** Read an integer numeral from string 'fmt' or return 'df' if +** there is no numeral +*/ +static int digit (int c) { return '0' <= c && c <= '9'; } + +static int getnum (const char **fmt, int df) { + if (!digit(**fmt)) /* no number? */ + return df; /* return default value */ else { - for (i = size - 1; i > 0; i--) { - buff[i] = (n & MC); - n = (n >> NB) | mask; - } - } - buff[i] = (n & MC); /* last byte */ - if (size < SZINT) { /* need test for overflow? */ - /* OK if there are only zeros left in higher bytes, - or only ones left (excluding non-signal bits in last byte) */ - return ((n & ~(lua_Unsigned)MC) == 0 || - (n | SM) == ~(lua_Unsigned)0); + int a = 0; + do { + a = a*10 + *((*fmt)++) - '0'; + } while (digit(**fmt) && a < (INT_MAX/10 - 10)); + return a; } - else return 1; /* no overflow can occur with full size */ } -static int dumpint_l (lua_State *L) { - char buff[MAXINTSIZE]; - lua_Integer n = luaL_checkinteger(L, 1); - int size = getintsize(L, 2); - int endian = getendian(L, 3); - if (dumpint(buff, n, endian, size)) - lua_pushlstring(L, buff, size); - else - luaL_error(L, "integer does not fit into given size (%d)", size); - return 1; +/* +** Read an integer numeral and raises an error if it is larger +** than the maximum size for integers. +*/ +static int getnumlimit (Header *h, const char **fmt, int df) { + int sz = getnum(fmt, df); + if (sz > MAXINTSIZE || sz <= 0) + luaL_error(h->L, "integral size (%d) out of limits [1,%d]", sz, MAXINTSIZE); + return sz; } -/* mask to check higher-order byte + signal bit of next (lower) byte */ -#define HIGHERBYTE1 (HIGHERBYTE | (HIGHERBYTE >> 1)) +/* +** Initialize Header +*/ +static void initheader (lua_State *L, Header *h) { + h->L = L; + h->islittle = nativeendian.little; + h->maxalign = 1; +} -static int undumpint (const char *buff, lua_Integer *res, - int littleendian, int size) { - lua_Unsigned n = 0; - int i; - for (i = 0; i < size; i++) { - if (i >= SZINT) { /* will throw away a byte? */ - /* check for overflow: it is OK to throw away leading zeros for a - positive number, leading ones for a negative number, and a - leading zero byte to allow unsigned integers with a 1 in - its "signal bit" */ - if (!((n & HIGHERBYTE1) == 0 || /* zeros for positive number */ - (n & HIGHERBYTE1) == HIGHERBYTE1 || /* ones for negative number */ - (i == size - 1 && (n & HIGHERBYTE) == 0))) /* leading zero */ - return 0; /* overflow */ +/* +** Read and classify next option. 'size' is filled with option's size. +*/ +static KOption getoption (Header *h, const char **fmt, int *size) { + int opt = *((*fmt)++); + *size = 0; /* default */ + switch (opt) { + case 'b': *size = sizeof(char); return Kint; + case 'B': *size = sizeof(char); return Kuint; + case 'h': *size = sizeof(short); return Kint; + case 'H': *size = sizeof(short); return Kuint; + case 'l': *size = sizeof(long); return Kint; + case 'L': *size = sizeof(long); return Kuint; + case 'j': *size = sizeof(lua_Integer); return Kint; + case 'J': *size = sizeof(lua_Integer); return Kuint; + case 'T': *size = sizeof(size_t); return Kuint; + case 'f': *size = sizeof(float); return Kfloat; + case 'd': *size = sizeof(double); return Kfloat; + case 'n': *size = sizeof(lua_Number); return Kfloat; + case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; + case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; + case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; + case 'c': *size = getnum(fmt, 1); return Kchar; + case 'z': return Kzstr; + case 'x': *size = 1; return Kpadding; + case 'X': return Kpaddalign; + case ' ': return Knop; + case '\0': return Keof; + case '<': h->islittle = 1; return Knop; + case '>': h->islittle = 0; return Knop; + case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); return Knop; + default: { + luaL_error(h->L, "invalid format option '%c'", opt); + return Knop; } - n <<= NB; - n |= (lua_Unsigned)(unsigned char)buff[littleendian ? size - 1 - i : i]; - } - if (size < SZINT) { /* need sign extension? */ - lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); - *res = (lua_Integer)((n ^ mask) - mask); /* do sign extension */ } - else - *res = (lua_Integer)n; - return 1; } -static int undumpint_l (lua_State *L) { - lua_Integer res; - size_t len; - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len); - int size = getintsize(L, 3); - int endian = getendian(L, 4); - luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1, - "string too short"); - if(undumpint(s + pos - 1, &res, endian, size)) - lua_pushinteger(L, res); - else - luaL_error(L, "result does not fit into a Lua integer"); - return 1; +/* +** Read, classify, and fill other details about the next option. +** 'psize' is filled with option's size, 'notoalign' with its +** alignment requirements. +** Local variable 'size' gets the size to be aligned. (Kpadal option +** always gets its full alignment, other options are limited by +** the maximum alignment ('maxalign). Kchar option needs no aligment +** despite its size. +*/ +static KOption getdetails (Header *h, size_t totalsize, + const char **fmt, int *psize, int *ntoalign) { + int align; + KOption opt; + do { + opt = getoption(h, fmt, psize); + } while (opt == Knop); /* skip no-op options */ + align = *psize; /* usually, alignment follows size */ + if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ + if (getoption(h, fmt, &align) == Kchar || align == 0) + luaL_argerror(h->L, 1, "invalid next option for option 'X'"); + } + if (align <= 1 || opt == Kchar) /* need no alignment? */ + *ntoalign = 0; + else { + if (align > h->maxalign) /* enforce maximum alignment */ + align = h->maxalign; + if ((align & (align - 1)) != 0) /* is 'align' not a power of 2? */ + luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); + *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); + } + return opt; } -static void correctendianness (lua_State *L, char *b, int size, int endianarg) { - int endian = getendian(L, endianarg); - if (endian != nativeendian.little) { /* not native endianness? */ - int i = 0; - while (i < --size) { - char temp = b[i]; - b[i++] = b[size]; - b[size] = temp; - } +static void packint (luaL_Buffer *b, lua_Unsigned n, + int islittle, int size, lua_Unsigned mask) { + char *buff = luaL_prepbuffsize(b, size); + int i; + for (i = 0; i < size - 1; i++) { + buff[islittle ? i : size - 1 - i] = (n & MC); + n = (n >> NB) | mask; } + buff[islittle ? i : size - 1 - i] = (n & MC); + luaL_addsize(b, size); /* add result to buffer */ } -static int getfloatsize (lua_State *L, int arg) { - const char *size = luaL_optstring(L, arg, "n"); - if (*size == 'n') return sizeof(lua_Number); - luaL_argcheck(L, *size == 'd' || *size == 'f', arg, - "size must be 'f'/'d'/'n'"); - return (*size == 'd' ? sizeof(double) : sizeof(float)); +/* +** Copy 'size' bytes from 'src' to 'dest', correcting endianness if +** given 'islittle' is different from native endianness. +*/ +static void copywithendian (volatile char *dest, volatile const char *src, + int size, int islittle) { + if (islittle == nativeendian.little) { + while (size-- != 0) + *(dest++) = *(src++); + } + else { + dest += size - 1; + while (size-- != 0) + *(dest--) = *(src++); + } } -static int dumpfloat_l (lua_State *L) { - float f; double d; - char *pn; /* pointer to number */ - lua_Number n = luaL_checknumber(L, 1); - int size = getfloatsize(L, 2); - if (size == sizeof(lua_Number)) - pn = (char*)&n; - else if (size == sizeof(float)) { - f = (float)n; - pn = (char*)&f; - } - else { /* native lua_Number may be neither float nor double */ - lua_assert(size == sizeof(double)); - d = (double)n; - pn = (char*)&d; +static int str_pack (lua_State *L) { + luaL_Buffer b; + Header h; + const char *fmt = luaL_checkstring(L, 1); /* format string */ + int arg = 1; /* current argument to pack */ + size_t totalsize = 0; /* accumulate total size of result */ + initheader(L, &h); + lua_pushnil(L); /* mark to separate arguments from string buffer */ + luaL_buffinit(L, &b); + for (;;) { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + totalsize += ntoalign + size; + while (ntoalign-- > 0) luaL_addchar(&b, '\0'); /* fill alignment */ + arg++; + switch (opt) { + case Kint: { /* signed integers */ + lua_Integer n = luaL_checkinteger(L, arg); + lua_Unsigned mask = (n < 0) ? HIGHERBYTE : 0; /* sign extension */ + if (size < SZINT) { /* need overflow check? */ + lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); + luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); + } + packint(&b, (lua_Unsigned)n, h.islittle, size, mask); + break; + } + case Kuint: { /* unsigned integers */ + lua_Integer n = luaL_checkinteger(L, arg); + if (size < SZINT) /* need overflow check? */ + luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), + arg, "unsigned overflow"); + packint(&b, (lua_Unsigned)n, h.islittle, size, 0); + break; + } + case Kfloat: { /* floating-point options */ + volatile Ftypes u; + char *buff = luaL_prepbuffsize(&b, size); + lua_Number n = luaL_checknumber(L, arg); /* get argument */ + if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ + else if (size == sizeof(u.d)) u.d = (double)n; + else u.n = n; + /* move 'u' to final result, correcting endianness if needed */ + copywithendian(buff, u.buff, size, h.islittle); + luaL_addsize(&b, size); + break; + } + case Kchar: { /* fixed-size string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, len == (size_t)size, arg, "wrong length"); + luaL_addlstring(&b, s, size); + break; + } + case Kstring: { /* strings with length count */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, size >= (int)sizeof(size_t) || + len < ((size_t)1 << (size * NB)), + arg, "string length does not fit in given size"); + packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ + luaL_addlstring(&b, s, len); + totalsize += len; + break; + } + case Kzstr: { /* zero-terminated string */ + size_t len; + const char *s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); + luaL_addlstring(&b, s, len); + luaL_addchar(&b, '\0'); /* add zero at the end */ + totalsize += len + 1; + break; + } + case Kpadding: luaL_addchar(&b, '\0'); /* go through */ + case Kpaddalign: case Knop: + arg--; /* undo increment */ + break; + case Keof: /* end of format */ + luaL_pushresult(&b); + return 1; + } } - correctendianness(L, pn, size, 3); - lua_pushlstring(L, pn, size); - return 1; } -static int undumpfloat_l (lua_State *L) { - lua_Number res; - size_t len; - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len); - int size = getfloatsize(L, 3); - luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1, - "string too short"); - if (size == sizeof(lua_Number)) { - memcpy(&res, s + pos - 1, size); - correctendianness(L, (char*)&res, size, 4); +static lua_Integer unpackint (lua_State *L, const char *str, + int islittle, int size, int issigned) { + lua_Unsigned res = 0; + int i; + int limit = (size <= SZINT) ? size : SZINT; + for (i = limit - 1; i >= 0; i--) { + res <<= NB; + res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; } - else if (size == sizeof(float)) { - float f; - memcpy(&f, s + pos - 1, size); - correctendianness(L, (char*)&f, size, 4); - res = (lua_Number)f; - } - else { /* native lua_Number may be neither float nor double */ - double d; - lua_assert(size == sizeof(double)); - memcpy(&d, s + pos - 1, size); - correctendianness(L, (char*)&d, size, 4); - res = (lua_Number)d; + if (size < SZINT) { /* real size smaller than lua_Integer? */ + if (issigned) { /* needs sign extension? */ + lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); + res = ((res ^ mask) - mask); /* do sign extension */ + } + } + else { /* must check unread bytes */ + int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; + for (i = limit; i < size; i++) { + if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) + luaL_error(L, "%d-bit integer does not fit into Lua Integer", size); + } + } + return (lua_Integer)res; +} + + +static int str_unpack (lua_State *L) { + Header h; + const char *fmt = luaL_checkstring(L, 1); + size_t ld; + const char *data = luaL_checklstring(L, 2, &ld); + size_t pos = (size_t)posrelat(luaL_optinteger(L, 3, 1), ld) - 1; + int n = 0; /* number of results */ + luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); + initheader(L, &h); + for (;;) { + int size, ntoalign; + KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); + if ((size_t)ntoalign + size > ~pos || pos + ntoalign + size > ld) + luaL_argerror(L, 2, "data string too short"); + pos += ntoalign; + /* stack space for item + next position */ + luaL_checkstack(L, 2, "too many results"); + n++; + switch (opt) { + case Kint: + case Kuint: { + lua_Integer res = unpackint(L, data + pos, h.islittle, size, + (opt == Kint)); + lua_pushinteger(L, res); + break; + } + case Kfloat: { + volatile Ftypes u; + lua_Number num; + copywithendian(u.buff, data + pos, size, h.islittle); + if (size == sizeof(u.f)) num = (lua_Number)u.f; + else if (size == sizeof(u.d)) num = (lua_Number)u.d; + else num = u.n; + lua_pushnumber(L, num); + break; + } + case Kchar: { + lua_pushlstring(L, data + pos, size); + break; + } + case Kstring: { + size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); + luaL_argcheck(L, pos + len + size <= ld, 2, "data string too short"); + lua_pushlstring(L, data + pos + size, len); + pos += len; + break; + } + case Kzstr: { + size_t len = (int)strlen(data + pos); + lua_pushlstring(L, data + pos, len); + pos += len + 1; /* skip final '\0' */ + break; + } + case Kpaddalign: case Kpadding: case Knop: + n--; /* undo increment */ + break; + case Keof: /* end of format */ + lua_pushinteger(L, pos + 1); /* next position */ + return n; + } + pos += size; } - lua_pushnumber(L, res); - return 1; } /* }====================================================== */ @@ -1176,10 +1355,8 @@ static const luaL_Reg strlib[] = { {"reverse", str_reverse}, {"sub", str_sub}, {"upper", str_upper}, - {"dumpfloat", dumpfloat_l}, - {"dumpint", dumpint_l}, - {"undumpfloat", undumpfloat_l}, - {"undumpint", undumpint_l}, + {"pack", str_pack}, + {"unpack", str_unpack}, {NULL, NULL} }; diff --git a/src/ltable.c b/src/ltable.c index 6ba80e3b..f7b836d5 100644 --- a/src/ltable.c +++ b/src/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.93 2014/07/29 16:22:24 roberto Exp $ +** $Id: ltable.c,v 2.96 2014/10/17 16:28:21 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -40,14 +40,19 @@ /* -** Maximum size of array part (MAXASIZE) is 2^MAXBITS. (SIZEINT is the -** minimum between size of int and size of LUA_INTEGER; array indices -** are limited by both types.) +** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is +** the largest integer such that MAXASIZE fits in an unsigned int. */ -#define SIZEINT \ - (sizeof(int) < sizeof(LUA_INTEGER) ? sizeof(int) : sizeof(LUA_INTEGER)) -#define MAXBITS cast_int(SIZEINT * CHAR_BIT - 2) -#define MAXASIZE (1 << MAXBITS) +#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) +#define MAXASIZE (1u << MAXABITS) + +/* +** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest +** integer such that 2^MAXHBITS fits in a signed int. (Note that the +** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still +** fits comfortably in an unsigned int.) +*/ +#define MAXHBITS (MAXABITS - 1) #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) @@ -139,29 +144,29 @@ static Node *mainposition (const Table *t, const TValue *key) { /* ** returns the index for `key' if `key' is an appropriate key to live in -** the array part of the table, -1 otherwise. +** the array part of the table, 0 otherwise. */ -static int arrayindex (const TValue *key) { +static unsigned int arrayindex (const TValue *key) { if (ttisinteger(key)) { lua_Integer k = ivalue(key); - if (0 < k && k <= MAXASIZE) /* is `key' an appropriate array index? */ - return cast_int(k); + if (0 < k && (lua_Unsigned)k <= MAXASIZE) + return cast(unsigned int, k); /* 'key' is an appropriate array index */ } - return -1; /* `key' did not match some condition */ + return 0; /* `key' did not match some condition */ } /* ** returns the index of a `key' for table traversals. First goes all ** elements in the array part, then elements in the hash part. The -** beginning of a traversal is signaled by -1. +** beginning of a traversal is signaled by 0. */ -static int findindex (lua_State *L, Table *t, StkId key) { - int i; - if (ttisnil(key)) return -1; /* first iteration */ +static unsigned int findindex (lua_State *L, Table *t, StkId key) { + unsigned int i; + if (ttisnil(key)) return 0; /* first iteration */ i = arrayindex(key); - if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ - return i-1; /* yes; that's the index (corrected to C) */ + if (i != 0 && i <= t->sizearray) /* is `key' inside array part? */ + return i; /* yes; that's the index */ else { int nx; Node *n = mainposition(t, key); @@ -172,11 +177,11 @@ static int findindex (lua_State *L, Table *t, StkId key) { deadvalue(gkey(n)) == gcvalue(key))) { i = cast_int(n - gnode(t, 0)); /* key index in hash table */ /* hash elements are numbered after array ones */ - return i + t->sizearray; + return (i + 1) + t->sizearray; } nx = gnext(n); if (nx == 0) - luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + luaG_runerror(L, "invalid key to 'next'"); /* key not found */ else n += nx; } } @@ -184,15 +189,15 @@ static int findindex (lua_State *L, Table *t, StkId key) { int luaH_next (lua_State *L, Table *t, StkId key) { - int i = findindex(L, t, key); /* find original element */ - for (i++; i < t->sizearray; i++) { /* try first array part */ + unsigned int i = findindex(L, t, key); /* find original element */ + for (; i < t->sizearray; i++) { /* try first array part */ if (!ttisnil(&t->array[i])) { /* a non-nil value? */ setivalue(key, i + 1); setobj2s(L, key+1, &t->array[i]); return 1; } } - for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ + for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ setobj2s(L, key, gkey(gnode(t, i))); setobj2s(L, key+1, gval(gnode(t, i))); @@ -209,19 +214,24 @@ int luaH_next (lua_State *L, Table *t, StkId key) { ** ============================================================== */ - -static int computesizes (int nums[], int *narray) { +/* +** Compute the optimal size for the array part of table 't'. 'nums' is a +** "count array" where 'nums[i]' is the number of integers in the table +** between 2^(i - 1) + 1 and 2^i. Put in '*narray' the optimal size, and +** return the number of elements that will go to that part. +*/ +static unsigned int computesizes (unsigned int nums[], unsigned int *narray) { int i; - int twotoi; /* 2^i */ - int a = 0; /* number of elements smaller than 2^i */ - int na = 0; /* number of elements to go to array part */ - int n = 0; /* optimal size for array part */ + unsigned int twotoi; /* 2^i */ + unsigned int a = 0; /* number of elements smaller than 2^i */ + unsigned int na = 0; /* number of elements to go to array part */ + unsigned int n = 0; /* optimal size for array part */ for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { if (nums[i] > 0) { a += nums[i]; if (a > twotoi/2) { /* more than half elements present? */ n = twotoi; /* optimal size (till now) */ - na = a; /* all elements smaller than n will go to array part */ + na = a; /* all elements up to 'n' will go to array part */ } } if (a == *narray) break; /* all elements already counted */ @@ -232,9 +242,9 @@ static int computesizes (int nums[], int *narray) { } -static int countint (const TValue *key, int *nums) { - int k = arrayindex(key); - if (k > 0) { /* is `key' an appropriate array index? */ +static int countint (const TValue *key, unsigned int *nums) { + unsigned int k = arrayindex(key); + if (k != 0) { /* is `key' an appropriate array index? */ nums[luaO_ceillog2(k)]++; /* count as such */ return 1; } @@ -243,20 +253,21 @@ static int countint (const TValue *key, int *nums) { } -static int numusearray (const Table *t, int *nums) { +static unsigned int numusearray (const Table *t, unsigned int *nums) { int lg; - int ttlg; /* 2^lg */ - int ause = 0; /* summation of `nums' */ - int i = 1; /* count to traverse all array keys */ - for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ - int lc = 0; /* counter */ - int lim = ttlg; + unsigned int ttlg; /* 2^lg */ + unsigned int ause = 0; /* summation of `nums' */ + unsigned int i = 1; /* count to traverse all array keys */ + /* traverse each slice */ + for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) { + unsigned int lc = 0; /* counter */ + unsigned int lim = ttlg; if (lim > t->sizearray) { lim = t->sizearray; /* adjust upper limit */ if (i > lim) break; /* no more elements to count */ } - /* count elements in range (2^(lg-1), 2^lg] */ + /* count elements in range (2^(lg - 1), 2^lg] */ for (; i <= lim; i++) { if (!ttisnil(&t->array[i-1])) lc++; @@ -268,9 +279,10 @@ static int numusearray (const Table *t, int *nums) { } -static int numusehash (const Table *t, int *nums, int *pnasize) { +static int numusehash (const Table *t, unsigned int *nums, + unsigned int *pnasize) { int totaluse = 0; /* total number of elements */ - int ause = 0; /* summation of `nums' */ + int ause = 0; /* elements added to 'nums' (can go to array part) */ int i = sizenode(t); while (i--) { Node *n = &t->node[i]; @@ -284,8 +296,8 @@ static int numusehash (const Table *t, int *nums, int *pnasize) { } -static void setarrayvector (lua_State *L, Table *t, int size) { - int i; +static void setarrayvector (lua_State *L, Table *t, unsigned int size) { + unsigned int i; luaM_reallocvector(L, t->array, t->sizearray, size, TValue); for (i=t->sizearray; i<size; i++) setnilvalue(&t->array[i]); @@ -293,7 +305,7 @@ static void setarrayvector (lua_State *L, Table *t, int size) { } -static void setnodevector (lua_State *L, Table *t, int size) { +static void setnodevector (lua_State *L, Table *t, unsigned int size) { int lsize; if (size == 0) { /* no elements to hash part? */ t->node = cast(Node *, dummynode); /* use common `dummynode' */ @@ -302,11 +314,11 @@ static void setnodevector (lua_State *L, Table *t, int size) { else { int i; lsize = luaO_ceillog2(size); - if (lsize > MAXBITS) + if (lsize > MAXHBITS) luaG_runerror(L, "table overflow"); size = twoto(lsize); t->node = luaM_newvector(L, size, Node); - for (i=0; i<size; i++) { + for (i = 0; i < (int)size; i++) { Node *n = gnode(t, i); gnext(n) = 0; setnilvalue(wgkey(n)); @@ -318,9 +330,11 @@ static void setnodevector (lua_State *L, Table *t, int size) { } -void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { - int i; - int oldasize = t->sizearray; +void luaH_resize (lua_State *L, Table *t, unsigned int nasize, + unsigned int nhsize) { + unsigned int i; + int j; + unsigned int oldasize = t->sizearray; int oldhsize = t->lsizenode; Node *nold = t->node; /* save old hash ... */ if (nasize > oldasize) /* array part must grow? */ @@ -338,8 +352,8 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { luaM_reallocvector(L, t->array, oldasize, nasize, TValue); } /* re-insert elements from hash part */ - for (i = twoto(oldhsize) - 1; i >= 0; i--) { - Node *old = nold+i; + for (j = twoto(oldhsize) - 1; j >= 0; j--) { + Node *old = nold + j; if (!ttisnil(gval(old))) { /* doesn't need barrier/invalidate cache, as entry was already present in the table */ @@ -351,18 +365,20 @@ void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { } -void luaH_resizearray (lua_State *L, Table *t, int nasize) { +void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { int nsize = isdummy(t->node) ? 0 : sizenode(t); luaH_resize(L, t, nasize, nsize); } - +/* +** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i +*/ static void rehash (lua_State *L, Table *t, const TValue *ek) { - int nasize, na; - int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */ + unsigned int nasize, na; + unsigned int nums[MAXABITS + 1]; int i; int totaluse; - for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ + for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */ nasize = numusearray(t, nums); /* count keys in array part */ totaluse = nasize; /* all those keys are integer keys */ totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ @@ -440,7 +456,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { Node *f = getfreepos(t); /* get a free place */ if (f == NULL) { /* cannot find a free place? */ rehash(L, t, key); /* grow table */ - /* whatever called 'newkey' take care of TM cache and GC barrier */ + /* whatever called 'newkey' takes care of TM cache and GC barrier */ return luaH_set(L, t, key); /* insert key into grown table */ } lua_assert(!isdummy(f)); @@ -478,7 +494,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { */ const TValue *luaH_getint (Table *t, lua_Integer key) { /* (1 <= key && key <= t->sizearray) */ - if (l_castS2U(key - 1) < cast(unsigned int, t->sizearray)) + if (l_castS2U(key - 1) < t->sizearray) return &t->array[key - 1]; else { Node *n = hashint(t, key); diff --git a/src/ltable.h b/src/ltable.h index 45ff45f2..53d25511 100644 --- a/src/ltable.h +++ b/src/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 2.19 2014/07/29 16:22:24 roberto Exp $ +** $Id: ltable.h,v 2.20 2014/09/04 18:15:29 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -30,14 +30,15 @@ LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, - TValue *value); + TValue *value); LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); LUAI_FUNC Table *luaH_new (lua_State *L); -LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize); -LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, + unsigned int nhsize); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); LUAI_FUNC void luaH_free (lua_State *L, Table *t); LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); LUAI_FUNC int luaH_getn (Table *t); diff --git a/src/ltablib.c b/src/ltablib.c index bc353866..908acfbc 100644 --- a/src/ltablib.c +++ b/src/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.73 2014/07/29 16:01:00 roberto Exp $ +** $Id: ltablib.c,v 1.77 2014/10/17 16:28:21 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -28,41 +28,25 @@ typedef struct { /* -** equivalent to 'lua_rawgeti', but not raw -*/ -static int geti (lua_State *L, int idx, lua_Integer n) { - lua_pushinteger(L, n); - return lua_gettable(L, idx); /* assume 'idx' is not negative */ -} - - -/* -** equivalent to 'lua_rawseti', but not raw -*/ -static void seti (lua_State *L, int idx, lua_Integer n) { - lua_pushinteger(L, n); - lua_rotate(L, -2, 1); /* exchange key and value */ - lua_settable(L, idx); /* assume 'idx' is not negative */ -} - - -/* ** Check that 'arg' has a table and set access functions in 'ta' to raw ** or non-raw according to the presence of corresponding metamethods. */ static void checktab (lua_State *L, int arg, TabA *ta) { - luaL_checktype(L, arg, LUA_TTABLE); - if (!lua_getmetatable(L, arg)) { /* fast track */ - ta->geti = lua_rawgeti; /* with no metatable, all is raw */ - ta->seti = lua_rawseti; - } - else { + ta->geti = NULL; ta->seti = NULL; + if (lua_getmetatable(L, arg)) { lua_pushliteral(L, "__index"); /* 'index' metamethod */ - ta->geti = (lua_rawget(L, -2) == LUA_TNIL) ? lua_rawgeti : geti; + if (lua_rawget(L, -2) != LUA_TNIL) + ta->geti = lua_geti; lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */ - ta->seti = (lua_rawget(L, -3) == LUA_TNIL) ? lua_rawseti : seti; + if (lua_rawget(L, -3) != LUA_TNIL) + ta->seti = lua_seti; lua_pop(L, 3); /* pop metatable plus both metamethods */ } + if (ta->geti == NULL || ta->seti == NULL) { + luaL_checktype(L, arg, LUA_TTABLE); /* must be table for raw methods */ + if (ta->geti == NULL) ta->geti = lua_rawgeti; + if (ta->seti == NULL) ta->seti = lua_rawseti; + } } @@ -107,7 +91,7 @@ static int tinsert (lua_State *L) { break; } default: { - return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + return luaL_error(L, "wrong number of arguments to 'insert'"); } } (*ta.seti)(L, 1, pos); /* t[pos] = v */ @@ -132,24 +116,22 @@ static int tremove (lua_State *L) { } -static int tcopy (lua_State *L) { +static int tmove (lua_State *L) { TabA ta; lua_Integer f = luaL_checkinteger(L, 2); lua_Integer e = luaL_checkinteger(L, 3); - lua_Integer t; - int tt = 4; /* destination table */ + lua_Integer t = luaL_checkinteger(L, 4); + int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ /* the following restriction avoids several problems with overflows */ luaL_argcheck(L, f > 0, 2, "initial position must be positive"); - if (lua_istable(L, tt)) - t = luaL_checkinteger(L, 5); - else { - tt = 1; /* destination table is equal to source */ - t = luaL_checkinteger(L, 4); - } if (e >= f) { /* otherwise, nothing to move */ lua_Integer n, i; - ta.geti = (!luaL_getmetafield(L, 1, "__index")) ? lua_rawgeti : geti; - ta.seti = (!luaL_getmetafield(L, tt, "__newindex")) ? lua_rawseti : seti; + ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL) + ? (luaL_checktype(L, 1, LUA_TTABLE), lua_rawgeti) + : lua_geti; + ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL) + ? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti) + : lua_seti; n = e - f + 1; /* number of elements to move */ if (t > f) { for (i = n - 1; i >= 0; i--) { @@ -172,8 +154,8 @@ static int tcopy (lua_State *L) { static void addfield (lua_State *L, luaL_Buffer *b, TabA *ta, lua_Integer i) { (*ta->geti)(L, 1, i); if (!lua_isstring(L, -1)) - luaL_error(L, "invalid value (%s) at index %d in table for " - LUA_QL("concat"), luaL_typename(L, -1), i); + luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", + luaL_typename(L, -1), i); luaL_addvalue(b); } @@ -355,7 +337,7 @@ static const luaL_Reg tab_funcs[] = { {"pack", pack}, {"unpack", unpack}, {"remove", tremove}, - {"copy", tcopy}, + {"move", tmove}, {"sort", sort}, {NULL, NULL} }; @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.213 2014/06/30 19:48:08 roberto Exp $ +** $Id: lua.c,v 1.217 2014/10/20 22:21:05 roberto Exp $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -134,9 +134,9 @@ static void print_usage (const char *badoption) { luai_writestringerror( "usage: %s [options] [script [args]]\n" "Available options are:\n" - " -e stat execute string " LUA_QL("stat") "\n" - " -i enter interactive mode after executing " LUA_QL("script") "\n" - " -l name require library " LUA_QL("name") "\n" + " -e stat execute string 'stat'\n" + " -i enter interactive mode after executing 'script'\n" + " -l name require library 'name'\n" " -v show version information\n" " -E ignore environment variables\n" " -- stop handling options\n" @@ -158,34 +158,34 @@ static void l_message (const char *pname, const char *msg) { /* ** Check whether 'status' is not OK and, if so, prints the error -** message on the top of the stack. Because this function can be called -** unprotected, it only accepts actual strings as error messages. (A -** coercion could raise a memory error.) +** message on the top of the stack. It assumes that the error object +** is a string, as it was either generated by Lua or by 'msghandler'. */ static int report (lua_State *L, int status) { if (status != LUA_OK) { - const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1) - : NULL; - if (msg == NULL) msg = "(error object is not a string)"; + const char *msg = lua_tostring(L, -1); l_message(progname, msg); - lua_pop(L, 1); + lua_pop(L, 1); /* remove message */ } return status; } /* -** Message handler to be used to run all chunks +** Message handler used to run all chunks */ static int msghandler (lua_State *L) { const char *msg = lua_tostring(L, 1); - if (msg) /* is error object a string? */ - luaL_traceback(L, L, msg, 1); /* use standard traceback */ - else if (!lua_isnoneornil(L, 1)) { /* non-string error object? */ - if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */ - lua_pushliteral(L, "(no error message)"); - } /* else no error object, does nothing */ - return 1; + if (msg == NULL) { /* is error object not a string? */ + if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */ + lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */ + return 1; /* that is the message */ + else + msg = lua_pushfstring(L, "(error object is a %s value)", + luaL_typename(L, 1)); + } + luaL_traceback(L, L, msg, 1); /* append a standard traceback */ + return 1; /* return the traceback */ } @@ -389,9 +389,8 @@ static void l_print (lua_State *L) { lua_getglobal(L, "print"); lua_insert(L, 1); if (lua_pcall(L, n, 0, 0) != LUA_OK) - l_message(progname, lua_pushfstring(L, - "error calling " LUA_QL("print") " (%s)", - lua_tostring(L, -1))); + l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)", + lua_tostring(L, -1))); } } @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.312 2014/07/31 13:44:30 roberto Exp $ +** $Id: lua.h,v 1.319 2014/10/17 19:17:55 roberto Exp $ ** Lua - A Scripting Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -19,7 +19,7 @@ #define LUA_VERSION_MAJOR "5" #define LUA_VERSION_MINOR "3" #define LUA_VERSION_NUM 503 -#define LUA_VERSION_RELEASE "0 (alpha)" +#define LUA_VERSION_RELEASE "0 (beta)" #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE @@ -94,7 +94,7 @@ typedef LUA_INTEGER lua_Integer; typedef LUA_UNSIGNED lua_Unsigned; /* type for continuation-function contexts */ -typedef LUA_CTXT lua_Ctx; +typedef LUA_KCONTEXT lua_KContext; /* @@ -105,7 +105,7 @@ typedef int (*lua_CFunction) (lua_State *L); /* ** Type for continuation functions */ -typedef int (*lua_KFunction) (lua_State *L, int status, lua_Ctx ctx); +typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); /* @@ -239,6 +239,7 @@ LUA_API int (lua_pushthread) (lua_State *L); LUA_API int (lua_getglobal) (lua_State *L, const char *var); LUA_API int (lua_gettable) (lua_State *L, int idx); LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n); LUA_API int (lua_rawget) (lua_State *L, int idx); LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); @@ -255,6 +256,7 @@ LUA_API int (lua_getuservalue) (lua_State *L, int idx); LUA_API void (lua_setglobal) (lua_State *L, const char *var); LUA_API void (lua_settable) (lua_State *L, int idx); LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n); LUA_API void (lua_rawset) (lua_State *L, int idx); LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n); LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); @@ -265,12 +267,12 @@ LUA_API void (lua_setuservalue) (lua_State *L, int idx); /* ** 'load' and 'call' functions (load and run Lua code) */ -LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, lua_Ctx ctx, - lua_KFunction k); +LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, + lua_KContext ctx, lua_KFunction k); #define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, - lua_Ctx ctx, lua_KFunction k); + lua_KContext ctx, lua_KFunction k); #define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, @@ -283,7 +285,7 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); /* ** coroutine functions */ -LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_Ctx ctx, +LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, lua_KFunction k); #define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); @@ -319,7 +321,7 @@ LUA_API int (lua_next) (lua_State *L, int idx); LUA_API void (lua_concat) (lua_State *L, int n); LUA_API void (lua_len) (lua_State *L, int idx); -LUA_API size_t (lua_strtonum) (lua_State *L, const char *s); +LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); @@ -377,7 +379,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); ** compatibility macros for unsigned conversions ** =============================================================== */ -#if defined(LUA_COMPAT_APIUNSIGNED) +#if defined(LUA_COMPAT_APIINTCASTS) #define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) #define lua_tounsignedx(L,i,is) ((lua_Integer)lua_tointegerx(L,i,is)) diff --git a/src/luaconf.h b/src/luaconf.h index d3db9267..ae395769 100644 --- a/src/luaconf.h +++ b/src/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.212 2014/07/24 19:33:29 roberto Exp $ +** $Id: luaconf.h,v 1.220 2014/10/21 14:38:46 roberto Exp $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -8,9 +8,6 @@ #ifndef lconfig_h #define lconfig_h -#include <limits.h> -#include <stddef.h> - /* ** ================================================================== @@ -20,20 +17,42 @@ /* -** =================================================================== +** {================================================================== @@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines type for -@@ Lua integers; +@@ Lua integers; you must define one of them. @@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines -@@ type for Lua floats. +@@ type for Lua floats. You must define one of them. +** +** These definitions set the numeric types for Lua. Lua should work fine +** with any mix of these previous options. The usual configurations +** are 64-bit integers and floats (the default) and 32-bit integers and +** floats (Small Lua, for restricted platforms). ** -** These definitions set the numeric types for Lua. Lua should work -** fine with any mix of these previous options. -** The usual configurations are 64-bit integers and floats (the default) -** and 32-bit integers and floats (Small Lua, for restricted hardware). +** Note that C compilers not compliant with C99 may not have +** support for 'long long'. In that case, you should not use option +** 'LUA_INT_LONGLONG'; use instead option 'LUA_32BITS' for Small Lua +** (see below), or LUA_INT_LONG plus LUA_REAL_DOUBLE for an interpreter +** with 32-bit integers and double floating-point numbers. ** ===================================================================== */ + +/* +** Just uncomment the next line for Small Lua; you can also define +** LUA_32BITS in the make file, but changing here you ensure that +** all software connected to Lua will be compiled with the same +** configuration. +*/ +/* #define LUA_32BITS */ + +#if !defined(LUA_32BITS) && !defined(LUA_ANSI) #define LUA_INT_LONGLONG #define LUA_REAL_DOUBLE +#else /* Lua 32 bits */ +#define LUA_INT_LONG +#define LUA_REAL_FLOAT +#endif + +/* }================================================================== */ /* @@ -51,6 +70,7 @@ #endif #if defined(LUA_WIN) +#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ANSI C functions */ #define LUA_DL_DLL #define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ #endif @@ -91,6 +111,9 @@ +#include <limits.h> +#include <stddef.h> + /* @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for @@ Lua libraries. @@ -220,7 +243,8 @@ /* @@ LUA_QL describes how error messages quote program elements. -** CHANGE it if you want a different appearance. +** Lua does not use these macros anymore; they are here for +** compatibility only. */ #define LUA_QL(x) "'" x "'" #define LUA_QS LUA_QL("%s") @@ -236,14 +260,10 @@ /* @@ luai_writestring/luai_writeline define how 'print' prints its results. -** They are only used in libraries and the stand-alone program. (The #if -** avoids including 'stdio.h' everywhere.) +** They are only used in libraries and the stand-alone program. */ -#if defined(LUA_LIB) || defined(lua_c) -#include <stdio.h> #define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) #define luai_writeline() (luai_writestring("\n", 1), fflush(stdout)) -#endif /* @@ luai_writestringerror defines how to print error messages. @@ -263,19 +283,20 @@ /* -@@ LUA_CTXT is the type of the context ('ctx') for continuation functions. -@@ It must be a numerical type; Lua will use 'intptr_t' if available. +@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation +@@ functions. It must be a numerical type; Lua will use 'intptr_t' if +@@ available. */ #if defined (LUA_USE_C99) #include <stdint.h> #if defined (INTPTR_MAX) /* even in C99 this type is optional */ -#define LUA_CTXT intptr_t +#define LUA_KCONTEXT intptr_t #endif #endif -#if !defined(LUA_CTXT) +#if !defined(LUA_KCONTEXT) /* default definition (the nearest thing to 'intptr_t' in C89) */ -#define LUA_CTXT ptrdiff_t +#define LUA_KCONTEXT ptrdiff_t #endif @@ -305,15 +326,16 @@ #define LUA_COMPAT_BITLIB /* -@@ LUA_COMPAT_IPAIRS controls the effectivness of the __ipairs metamethod. +@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod. */ #define LUA_COMPAT_IPAIRS /* -@@ LUA_COMPAT_APIUNSIGNED controls the presence of macros for -** manipulating unsigned integers (lua_pushunsigned, lua_tounsigned, etc.) +@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for +** manipulating other integer types (lua_pushunsigned, lua_tounsigned, +** luaL_checkint, luaL_checklong, etc.) */ -#define LUA_COMPAT_APIUNSIGNED +#define LUA_COMPAT_APIINTCASTS /* @@ -525,16 +547,11 @@ #endif /* } */ -#if defined(LUA_ANSI) -/* C89 does not support 'opf' variants for math functions */ +#if !defined(LUA_USE_C99) +/* 'strtof' and 'opf' variants for math functions are C99 */ #undef l_mathop -#define l_mathop(op) (lua_Number)op -#endif - - -#if defined(LUA_ANSI) || defined(_WIN32) -/* C89 and Windows do not support 'strtof'... */ #undef lua_str2number +#define l_mathop(op) (lua_Number)op #define lua_str2number(s,p) ((lua_Number)strtod((s), (p))) #endif @@ -652,6 +669,10 @@ #else +#if !defined(LLONG_MAX) +#error "Compiler does not support 'long long'. See file 'luaconf.h' line 24" +#endif + #define LUA_INTEGER long long #define LUA_INTEGER_FRMLEN "ll" diff --git a/src/lutf8lib.c b/src/lutf8lib.c index 1e848def..de139296 100644 --- a/src/lutf8lib.c +++ b/src/lutf8lib.c @@ -1,5 +1,5 @@ /* -** $Id: lutf8lib.c,v 1.10 2014/07/16 13:56:14 roberto Exp $ +** $Id: lutf8lib.c,v 1.12 2014/10/15 14:31:10 roberto Exp $ ** Standard library for UTF-8 manipulation ** See Copyright Notice in lua.h */ @@ -123,9 +123,9 @@ static int codepoint (lua_State *L) { static void pushutfchar (lua_State *L, int arg) { - int code = luaL_checkint(L, arg); + lua_Integer code = luaL_checkinteger(L, arg); luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); - lua_pushfstring(L, "%U", code); + lua_pushfstring(L, "%U", (long)code); } @@ -157,7 +157,7 @@ static int utfchar (lua_State *L) { static int byteoffset (lua_State *L) { size_t len; const char *s = luaL_checklstring(L, 1, &len); - int n = luaL_checkint(L, 2); + lua_Integer n = luaL_checkinteger(L, 2); lua_Integer posi = (n >= 0) ? 1 : len + 1; posi = u_posrelat(luaL_optinteger(L, 3, posi), len); luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, @@ -239,7 +239,7 @@ static struct luaL_Reg funcs[] = { {"len", utflen}, {"codes", iter_codes}, /* placeholders */ - {"charpatt", NULL}, + {"charpattern", NULL}, {NULL, NULL} }; @@ -247,7 +247,7 @@ static struct luaL_Reg funcs[] = { LUAMOD_API int luaopen_utf8 (lua_State *L) { luaL_newlib(L, funcs); lua_pushliteral(L, UTF8PATT); - lua_setfield(L, -2, "charpatt"); + lua_setfield(L, -2, "charpattern"); return 1; } @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.222 2014/07/30 14:42:44 roberto Exp $ +** $Id: lvm.c,v 2.224 2014/10/17 16:28:21 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -1033,13 +1033,13 @@ void luaV_execute (lua_State *L) { else { /* try making all values floats */ lua_Number ninit; lua_Number nlimit; lua_Number nstep; if (!tonumber(plimit, &nlimit)) - luaG_runerror(L, LUA_QL("for") " limit must be a number"); + luaG_runerror(L, "'for' limit must be a number"); setfltvalue(plimit, nlimit); if (!tonumber(pstep, &nstep)) - luaG_runerror(L, LUA_QL("for") " step must be a number"); + luaG_runerror(L, "'for' step must be a number"); setfltvalue(pstep, nstep); if (!tonumber(init, &ninit)) - luaG_runerror(L, LUA_QL("for") " initial value must be a number"); + luaG_runerror(L, "'for' initial value must be a number"); setfltvalue(init, luai_numsub(L, ninit, nstep)); } ci->u.l.savedpc += GETARG_sBx(i); @@ -1067,7 +1067,7 @@ void luaV_execute (lua_State *L) { vmcase(OP_SETLIST, int n = GETARG_B(i); int c = GETARG_C(i); - int last; + unsigned int last; Table *h; if (n == 0) n = cast_int(L->top - ra) - 1; if (c == 0) { @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 2.33 2014/07/30 14:42:44 roberto Exp $ +** $Id: lvm.h,v 2.34 2014/08/01 17:24:02 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -16,14 +16,14 @@ #if !defined(LUA_NOCVTN2S) #define cvt2str(o) ttisnumber(o) #else -#define cvt2str(o) 0 /* no convertion from numbers to strings */ +#define cvt2str(o) 0 /* no conversion from numbers to strings */ #endif #if !defined(LUA_NOCVTS2N) #define cvt2num(o) ttisstring(o) #else -#define cvt2num(o) 0 /* no convertion from strings to numbers */ +#define cvt2num(o) 0 /* no conversion from strings to numbers */ #endif |