1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
/* implementation for lib2-v2 */
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
static int id (lua_State *L) {
lua_pushboolean(L, 1);
lua_insert(L, 1);
return lua_gettop(L);
}
struct STR {
void *ud;
lua_Alloc allocf;
};
static void *t_freestr (void *ud, void *ptr, size_t osize, size_t nsize) {
struct STR *blk = (struct STR*)ptr - 1;
blk->allocf(blk->ud, blk, sizeof(struct STR) + osize, 0);
return NULL;
}
static int newstr (lua_State *L) {
size_t len;
const char *str = luaL_checklstring(L, 1, &len);
void *ud;
lua_Alloc allocf = lua_getallocf(L, &ud);
struct STR *blk = (struct STR*)allocf(ud, NULL, 0,
len + 1 + sizeof(struct STR));
if (blk == NULL) { /* allocation error? */
lua_pushliteral(L, "not enough memory");
lua_error(L); /* raise a memory error */
}
blk->ud = ud; blk->allocf = allocf;
memcpy(blk + 1, str, len + 1);
lua_pushexternalstring(L, (char *)(blk + 1), len, t_freestr, L);
return 1;
}
/*
** Create an external string and keep it in the registry, so that it
** will test that the library code is still available (to deallocate
** this string) when closing the state.
*/
static void initstr (lua_State *L) {
lua_pushcfunction(L, newstr);
lua_pushstring(L,
"012345678901234567890123456789012345678901234567890123456789");
lua_call(L, 1, 1); /* call newstr("0123...") */
luaL_ref(L, LUA_REGISTRYINDEX); /* keep string in the registry */
}
static const struct luaL_Reg funcs[] = {
{"id", id},
{"newstr", newstr},
{NULL, NULL}
};
LUAMOD_API int luaopen_lib2 (lua_State *L) {
lua_settop(L, 2);
lua_setglobal(L, "y"); /* y gets 2nd parameter */
lua_setglobal(L, "x"); /* x gets 1st parameter */
initstr(L);
luaL_newlib(L, funcs);
return 1;
}
|