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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
/*
** (C) 2007-2009 Tomi Belan
** see LICENSE and NOTICE for details
** derived from lua.c in the Lua distribution (MIT license)
*/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
static lua_State *globalL = NULL;
static const char *progname = "error";
#define err_message(msg) (fprintf(stderr, "%s: %s\n", progname, (msg)), fflush(stderr), EXIT_FAILURE)
static int report (lua_State *L, int status) {
if (status && !lua_isnil(L, -1)) {
const char *msg = lua_tostring(L, -1);
err_message(msg ? msg : "(error message is not a string)");
lua_pop(L, 1);
}
return status;
}
static void sigint_luahook (lua_State *L, lua_Debug *ar) {
(void)ar; /* unused arg. */
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "interrupted!");
}
static void sigint_handler (int i) {
err_message("got SIGINT, raising exception (use ^C again if it gets stuck)");
signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
terminate process (default action) */
lua_sethook(globalL, sigint_luahook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
static void close_lua () {
lua_gc(globalL, LUA_GCCOLLECT, 0);
lua_close(globalL);
}
int main (int argc, char **argv) {
lua_State *L;
int i;
if(argv[0] && argv[0][0])
progname = argv[0];
/* initialize Lua */
if((globalL = L = lua_open()) == NULL)
return err_message("Could not initialize Lua");
atexit(close_lua);
/* load Lua libraries and code */
luaL_openlibs(L);
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
lua_remove(L, -2); /* package */
#define LIB(id) int luaopen_##id(lua_State *); lua_pushcfunction(L, luaopen_##id); lua_setfield(L, -2, #id)
/* ftgl requires gl, gl requires SDL, buf requires SDL */
LIB(bit);
LIB(SDL);
LIB(gl);
LIB(ftgl);
LIB(lfs);
LIB(win);
LIB(zlib);
LIB(buf);
#define CHUNK(id,name) \
if(report(L, luaL_loadbuffer(L, _chunk_##id, \
sizeof(_chunk_##id)/sizeof(char)-1, "=" name))) \
return EXIT_FAILURE; \
lua_setfield(L, -2, name);
#include "chunks.h"
lua_getfield(L, -1, "launcher");
lua_remove(L, -2); /* package.preload */
if(!lua_isfunction(L, -1))
return err_message("package.preload.launcher not found");
/* start the LuaJIT optimizer */
#ifdef LUA_JITLIBNAME
if(report(L, luaL_dostring(L, "require'jit.opt'.start()")))
return EXIT_FAILURE;
#endif
/* load and run the program */
lua_createtable(L, 1, argc - 1);
for(i = 0; i < argc; i++) {
lua_pushstring(L, argv[i]);
lua_rawseti(L, -2, i);
}
lua_setglobal(L, "arg");
signal(SIGINT, sigint_handler);
if(report(L, lua_pcall(L, 0, 0, 0)))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
|