aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Janda <siffiejoe@gmx.net>2015-01-21 14:34:11 +0100
committerPhilipp Janda <siffiejoe@gmx.net>2015-01-21 14:34:11 +0100
commitc57750c925553f627701f2c4897ee6bd6488c7c1 (patch)
tree465e24fcc87ab8a49baf3e4dec380871275cd486
parent866cb79f65c844b3fcfa99d2caa4bf19930dbc6d (diff)
downloadlua-compat-5.3-c57750c925553f627701f2c4897ee6bd6488c7c1.tar.gz
lua-compat-5.3-c57750c925553f627701f2c4897ee6bd6488c7c1.tar.bz2
lua-compat-5.3-c57750c925553f627701f2c4897ee6bd6488c7c1.zip
backport Lua 5.2/5.3 buffer API for Lua 5.1
-rw-r--r--README.md4
-rw-r--r--c-api/compat-5.3.c57
-rw-r--r--c-api/compat-5.3.h55
-rwxr-xr-xtests/test.lua3
-rw-r--r--tests/testmod.c15
5 files changed, 127 insertions, 7 deletions
diff --git a/README.md b/README.md
index c04d2d1..359cc3f 100644
--- a/README.md
+++ b/README.md
@@ -129,6 +129,7 @@ For Lua 5.1 additionally:
129* `luaL_fileresult` 129* `luaL_fileresult`
130* `luaL_checkversion` (with empty body, only to avoid compile errors) 130* `luaL_checkversion` (with empty body, only to avoid compile errors)
131* `luaL_tolstring` 131* `luaL_tolstring`
132* `luaL_buffinitsize`, `luaL_prepbuffsize`, and `luaL_pushresultsize`
132* `lua_pushunsigned`, `lua_tounsignedx`, `lua_tounsigned`, 133* `lua_pushunsigned`, `lua_tounsignedx`, `lua_tounsigned`,
133 `luaL_checkunsigned`, `luaL_optunsigned`, if 134 `luaL_checkunsigned`, `luaL_optunsigned`, if
134 `LUA_COMPAT_APIINTCASTS` is defined. 135 `LUA_COMPAT_APIINTCASTS` is defined.
@@ -149,12 +150,9 @@ For Lua 5.1 additionally:
149 * `lua_upvaluejoin` (5.1) 150 * `lua_upvaluejoin` (5.1)
150 * `lua_version` (5.1) 151 * `lua_version` (5.1)
151 * `lua_yieldk` (5.1) 152 * `lua_yieldk` (5.1)
152 * `luaL_buffinitsize` (5.1)
153 * `luaL_execresult` (5.1) 153 * `luaL_execresult` (5.1)
154 * `luaL_loadbufferx` (5.1) 154 * `luaL_loadbufferx` (5.1)
155 * `luaL_loadfilex` (5.1) 155 * `luaL_loadfilex` (5.1)
156 * `luaL_prepbuffsize` (5.1)
157 * `luaL_pushresultsize` (5.1)
158 156
159## See also 157## See also
160 158
diff --git a/c-api/compat-5.3.c b/c-api/compat-5.3.c
index a539aed..8db5189 100644
--- a/c-api/compat-5.3.c
+++ b/c-api/compat-5.3.c
@@ -391,6 +391,63 @@ COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
391#endif /* not COMPAT53_IS_LUAJIT */ 391#endif /* not COMPAT53_IS_LUAJIT */
392 392
393 393
394COMPAT53_API void luaL_buffinit (lua_State *L, luaL_Buffer_53 *B) {
395 /* make it crash if used via pointer to a 5.1-style luaL_Buffer */
396 B->b.p = NULL;
397 B->b.L = NULL;
398 B->b.lvl = 0;
399 /* reuse the buffer from the 5.1-style luaL_Buffer though! */
400 B->ptr = B->b.buffer;
401 B->capacity = LUAL_BUFFERSIZE;
402 B->nelems = 0;
403 B->L2 = L;
404}
405
406
407COMPAT53_API char *luaL_prepbuffsize (luaL_Buffer_53 *B, size_t s) {
408 if (B->capacity - B->nelems < s) { /* needs to grow */
409 char* newptr = NULL;
410 size_t newcap = B->capacity * 2;
411 if (newcap - B->nelems < s)
412 newcap = B->nelems + s;
413 if (newcap < B->capacity) /* overflow */
414 luaL_error(B->L2, "buffer too large");
415 newptr = lua_newuserdata(B->L2, newcap);
416 memcpy(newptr, B->ptr, B->nelems);
417 if (B->ptr != B->b.buffer)
418 lua_replace(B->L2, -2); /* remove old buffer */
419 B->ptr = newptr;
420 B->capacity = newcap;
421 }
422 return B->ptr+B->nelems;
423}
424
425
426COMPAT53_API void luaL_addlstring (luaL_Buffer_53 *B, const char *s, size_t l) {
427 memcpy(luaL_prepbuffsize(B, l), s, l);
428 luaL_addsize(B, l);
429}
430
431
432COMPAT53_API void luaL_addvalue (luaL_Buffer_53 *B) {
433 size_t len = 0;
434 const char *s = lua_tolstring(B->L2, -1, &len);
435 if (!s)
436 luaL_error(B->L2, "cannot convert value to string");
437 if (B->ptr != B->b.buffer)
438 lua_insert(B->L2, -2); /* userdata buffer must be at stack top */
439 luaL_addlstring(B, s, len);
440 lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1);
441}
442
443
444void luaL_pushresult (luaL_Buffer_53 *B) {
445 lua_pushlstring(B->L2, B->ptr, B->nelems);
446 if (B->ptr != B->b.buffer)
447 lua_replace(B->L2, -2); /* remove userdata buffer */
448}
449
450
394#endif /* Lua 5.1 */ 451#endif /* Lua 5.1 */
395 452
396 453
diff --git a/c-api/compat-5.3.h b/c-api/compat-5.3.h
index 8f38719..51bf7eb 100644
--- a/c-api/compat-5.3.h
+++ b/c-api/compat-5.3.h
@@ -3,6 +3,7 @@
3 3
4#include <stddef.h> 4#include <stddef.h>
5#include <limits.h> 5#include <limits.h>
6#include <string.h>
6#include <lua.h> 7#include <lua.h>
7#include <lauxlib.h> 8#include <lauxlib.h>
8#include <lualib.h> 9#include <lualib.h>
@@ -45,12 +46,9 @@
45 * lua_upvaluejoin 46 * lua_upvaluejoin
46 * lua_version 47 * lua_version
47 * lua_yieldk 48 * lua_yieldk
48 * luaL_buffinitsize
49 * luaL_execresult 49 * luaL_execresult
50 * luaL_loadbufferx 50 * luaL_loadbufferx
51 * luaL_loadfilex 51 * luaL_loadfilex
52 * luaL_prepbuffsize
53 * luaL_pushresultsize
54 */ 52 */
55 53
56/* PUC-Rio Lua uses lconfig_h as include guard for luaconf.h, 54/* PUC-Rio Lua uses lconfig_h as include guard for luaconf.h,
@@ -80,6 +78,15 @@ typedef struct luaL_Stream {
80 78
81typedef size_t lua_Unsigned; 79typedef size_t lua_Unsigned;
82 80
81typedef struct luaL_Buffer_53 {
82 luaL_Buffer b; /* make incorrect code crash! */
83 char *ptr;
84 size_t nelems;
85 size_t capacity;
86 lua_State *L2;
87} luaL_Buffer_53;
88#define luaL_Buffer luaL_Buffer_53
89
83#define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex) 90#define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
84COMPAT53_API int lua_absindex (lua_State *L, int i); 91COMPAT53_API int lua_absindex (lua_State *L, int i);
85 92
@@ -156,6 +163,46 @@ COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname);
156#define lua_pcallk(L, na, nr, err, ctx, cont) \ 163#define lua_pcallk(L, na, nr, err, ctx, cont) \
157 ((void)(ctx), (void)(cont), lua_pcall(L, na, nr, err)) 164 ((void)(ctx), (void)(cont), lua_pcall(L, na, nr, err))
158 165
166#define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53)
167COMPAT53_API void luaL_buffinit (lua_State *L, luaL_Buffer_53 *B);
168
169#define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53)
170COMPAT53_API char *luaL_prepbuffsize (luaL_Buffer_53 *B, size_t s);
171
172#define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53)
173COMPAT53_API void luaL_addlstring (luaL_Buffer_53 *B, const char *s, size_t l);
174
175#define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53)
176COMPAT53_API void luaL_addvalue (luaL_Buffer_53 *B);
177
178#define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53)
179COMPAT53_API void luaL_pushresult (luaL_Buffer_53 *B);
180
181#undef luaL_buffinitsize
182#define luaL_buffinitsize(L, B, s) \
183 (luaL_buffinit(L, B), luaL_prepbuffsize(B, s))
184
185#undef luaL_prepbuffer
186#define luaL_prepbuffer(B) \
187 luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
188
189#undef luaL_addchar
190#define luaL_addchar(B, c) \
191 ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize(B, 1)), \
192 ((B)->ptr[(B)->nelems++] = (c)))
193
194#undef luaL_addsize
195#define luaL_addsize(B, s) \
196 ((B)->nelems += (s))
197
198#undef luaL_addstring
199#define luaL_addstring(B, s) \
200 luaL_addlstring(B, s, strlen(s))
201
202#undef luaL_pushresultsize
203#define luaL_pushresultsize(B, s) \
204 (luaL_addsize(B, s), luaL_pushresult(B))
205
159#if defined(LUA_COMPAT_APIINTCASTS) 206#if defined(LUA_COMPAT_APIINTCASTS)
160#define lua_pushunsigned(L, n) \ 207#define lua_pushunsigned(L, n) \
161 lua_pushinteger(L, (lua_Integer)(n)) 208 lua_pushinteger(L, (lua_Integer)(n))
@@ -216,7 +263,7 @@ COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s);
216#define luaL_getmetafield(L, o, e) \ 263#define luaL_getmetafield(L, o, e) \
217 (luaL_getmetafield(L, o, e) ? lua_type(L, -1) : LUA_TNIL) 264 (luaL_getmetafield(L, o, e) ? lua_type(L, -1) : LUA_TNIL)
218 265
219#define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_) 266#define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53)
220COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, 267COMPAT53_API void luaL_requiref (lua_State *L, const char *modname,
221 lua_CFunction openf, int glb ); 268 lua_CFunction openf, int glb );
222 269
diff --git a/tests/test.lua b/tests/test.lua
index 98259fe..83e174e 100755
--- a/tests/test.lua
+++ b/tests/test.lua
@@ -679,5 +679,8 @@ local t = setmetatable({}, {
679 __tostring = function(v) return nil end 679 __tostring = function(v) return nil end
680}) 680})
681print(pcall(mod.tolstring, t)) 681print(pcall(mod.tolstring, t))
682
683___''
684print(mod.buffer())
682___'' 685___''
683 686
diff --git a/tests/testmod.c b/tests/testmod.c
index 2c6242b..f89b10a 100644
--- a/tests/testmod.c
+++ b/tests/testmod.c
@@ -242,6 +242,20 @@ static int test_tolstring (lua_State *L) {
242 return 2; 242 return 2;
243} 243}
244 244
245static int test_buffer (lua_State *L) {
246 luaL_Buffer b;
247 char *p = luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE+1);
248 p[0] = 'a';
249 p[1] = 'b';
250 luaL_addsize(&b, 2);
251 luaL_addstring(&b, "c");
252 lua_pushliteral(L, "d");
253 luaL_addvalue(&b);
254 luaL_addchar(&b, 'e');
255 luaL_pushresult(&b);
256 return 1;
257}
258
245 259
246static const luaL_Reg funcs[] = { 260static const luaL_Reg funcs[] = {
247 { "isinteger", test_isinteger }, 261 { "isinteger", test_isinteger },
@@ -262,6 +276,7 @@ static const luaL_Reg funcs[] = {
262 { "uservalue", test_uservalue }, 276 { "uservalue", test_uservalue },
263 { "globals", test_globals }, 277 { "globals", test_globals },
264 { "tolstring", test_tolstring }, 278 { "tolstring", test_tolstring },
279 { "buffer", test_buffer },
265 { NULL, NULL } 280 { NULL, NULL }
266}; 281};
267 282