aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 00000000..6cefe212
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,160 @@
1#include <lua.h>
2#include <lualib.h>
3#include <lauxlib.h>
4#include <errno.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8typedef struct {
9 char* module_name;
10 char* source_name;
11 int length;
12 const unsigned char* code;
13} Gen;
14
15#include "gen/gen.h"
16#include "gen/libraries.h"
17
18static const char* progname = "luarocks";
19
20/* portable alerts, from srlua */
21#ifdef _WIN32
22#include <windows.h>
23#define alert(message) MessageBox(NULL, message, progname, MB_ICONERROR | MB_OK)
24#define getprogname() char name[MAX_PATH]; argv[0]= GetModuleFileName(NULL,name,sizeof(name)) ? name : NULL;
25#else
26#define alert(message) fprintf(stderr,"%s: %s\n", progname, message)
27#define getprogname()
28#endif
29
30static int registry_key;
31
32/* fatal error, from srlua */
33static void fatal(const char* message) {
34 alert(message);
35 exit(EXIT_FAILURE);
36}
37
38static void load_main(lua_State* L) {
39 #include "gen/main.h"
40
41 if (luaL_loadbuffer(L, luarocks_gen_main, sizeof(luarocks_gen_main), progname) != LUA_OK) {
42 fatal(lua_tostring(L, -1));
43 }
44}
45
46
47static void declare_modules(lua_State* L) {
48 lua_settop(L, 0); /* */
49 lua_newtable(L); /* modules */
50 lua_pushlightuserdata(L, (void*) &registry_key); /* modules registry_key */
51 lua_pushvalue(L, 1); /* modules registry_key modules */
52 lua_rawset(L, LUA_REGISTRYINDEX); /* modules */
53
54 for (int i = 0; GEN[i].module_name; i++) {
55 const Gen* entry = &GEN[i];
56 luaL_loadbuffer(L, entry->code, entry->length, entry->source_name);
57 lua_setfield(L, 1, entry->module_name);
58 }
59}
60
61
62/* custom package loader */
63static int pkg_loader(lua_State* L) {
64 lua_pushlightuserdata(L, (void*) &registry_key); /* modname ? registry_key */
65 lua_rawget(L, LUA_REGISTRYINDEX); /* modname ? modules */
66 lua_pushvalue(L, -1); /* modname ? modules modules */
67 lua_pushvalue(L, 1); /* modname ? modules modules modname */
68 lua_gettable(L, -2); /* modname ? modules mod */
69 if (lua_type(L, -1) == LUA_TNIL) {
70 lua_pop(L, 1); /* modname ? modules */
71 lua_pushvalue(L, 1); /* modname ? modules modname */
72 lua_pushliteral(L, ".init"); /* modname ? modules modname ".init" */
73 lua_concat(L, 2); /* modname ? modules modname..".init" */
74 lua_gettable(L, -2); /* modname ? mod */
75 }
76 return 1;
77}
78
79static void install_pkg_loader(lua_State* L) {
80 lua_settop(L, 0); /* */
81 lua_getglobal(L, "table"); /* table */
82 lua_getfield(L, -1, "insert"); /* table table.insert */
83 lua_getglobal(L, "package"); /* table table.insert package */
84 lua_getfield(L, -1, "searchers"); /* table table.insert package package.searchers */
85 if (lua_type(L, -1) == LUA_TNIL) {
86 lua_pop(L, 1);
87 lua_getfield(L, -1, "loaders"); /* table table.insert package package.loaders */
88 }
89 lua_copy(L, 4, 3); /* table table.insert package.searchers */
90 lua_settop(L, 3); /* table table.insert package.searchers */
91 lua_pushnumber(L, 1); /* table table.insert package.searchers 1 */
92 lua_pushcfunction(L, pkg_loader); /* table table.insert package.searchers 1 pkg_loader */
93 lua_call(L, 3, 0); /* table */
94 lua_settop(L, 0); /* */
95}
96
97/* main script launcher, from srlua */
98static int pmain(lua_State *L) {
99 int argc = lua_tointeger(L, 1);
100 char** argv = lua_touserdata(L, 2);
101 int i;
102 load_main(L);
103 lua_createtable(L, argc, 0);
104 for (i = 0; i < argc; i++) {
105 lua_pushstring(L, argv[i]);
106 lua_rawseti(L, -2, i);
107 }
108 lua_setglobal(L, "arg");
109 luaL_checkstack(L, argc - 1, "too many arguments to script");
110 for (i = 1; i < argc; i++) {
111 lua_pushstring(L, argv[i]);
112 }
113 lua_call(L, argc - 1, 0);
114 return 0;
115}
116
117/* error handler, from luac */
118static int msghandler (lua_State *L) {
119 /* is error object not a string? */
120 const char *msg = lua_tostring(L, 1);
121 if (msg == NULL) {
122 /* does it have a metamethod that produces a string */
123 if (luaL_callmeta(L, 1, "__tostring") && lua_type(L, -1) == LUA_TSTRING) {
124 /* then that is the message */
125 return 1;
126 } else {
127 msg = lua_pushfstring(L, "(error object is a %s value)", luaL_typename(L, 1));
128 }
129 }
130 /* append a standard traceback */
131 luaL_traceback(L, L, msg, 1);
132 return 1;
133}
134
135/* main function, from srlua */
136int main(int argc, char** argv) {
137 lua_State* L;
138 getprogname();
139 if (argv[0] == NULL) {
140 fatal("cannot locate this executable");
141 }
142 L = luaL_newstate();
143 if (L == NULL) {
144 fatal("not enough memory for state");
145 }
146 luaL_openlibs(L);
147 install_pkg_loader(L);
148 declare_libraries(L);
149 declare_modules(L);
150 lua_pushcfunction(L, &msghandler);
151 lua_pushcfunction(L, &pmain);
152 lua_pushinteger(L, argc);
153 lua_pushlightuserdata(L, argv);
154 if (lua_pcall(L, 2, 0, -4) != 0) {
155 fatal(lua_tostring(L, -1));
156 }
157 lua_close(L);
158 return EXIT_SUCCESS;
159}
160