]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ned/server/src/lua.cc
update
[l4.git] / l4 / pkg / ned / server / src / lua.cc
1 /*
2  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *          Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10
11 #include <l4/sys/err.h>
12
13 #include <lua.h>
14 #include <lauxlib.h>
15 #include <lualib.h>
16
17 #include <cstdio>
18 #include <cstring>
19 #include <unistd.h>
20 #include <getopt.h>
21
22 #ifdef USE_READLINE
23 #include <readline/history.h>
24 #include <readline/readline.h>
25 #endif
26
27 #include "lua_cap.h"
28 #include "lua.h"
29
30 static Lua::Lib *_lua_init;
31
32 extern char const _binary_ned_lua_start[];
33 extern char const _binary_ned_lua_end[];
34
35 Lua::Lib::Lib(Prio prio) : _prio(prio), _next(0)
36 {
37   Lib **f = &_lua_init;
38   while (*f && (*f)->prio() < prio)
39     f = &(*f)->_next;
40
41   _next = *f;
42   *f = this;
43 }
44
45 void
46 Lua::Lib::run_init(lua_State *l)
47 {
48   for (Lib *c = _lua_init; c; c = c->_next)
49     c->init(l);
50 }
51
52
53 static const luaL_Reg libs[] =
54 {
55   { "", luaopen_base },
56 // { LUA_IOLIBNAME, luaopen_io },
57   { LUA_STRLIBNAME, luaopen_string },
58   {LUA_LOADLIBNAME, luaopen_package},
59   {LUA_DBLIBNAME, luaopen_debug},
60   { NULL, NULL }
61 };
62
63 static char const *const options = "+i";
64 static struct option const loptions[] =
65 {{"interactive", 0, NULL, 'i' },
66  {0, 0, 0, 0}};
67
68 int lua(int argc, char const *const *argv)
69 {
70
71   printf("Ned says: Hi World!\n");
72
73   bool interactive = false;
74
75   if (argc < 2)
76     interactive = true;
77
78   int opt;
79   while ((opt = getopt_long(argc, const_cast<char *const*>(argv), options, loptions, NULL)) != -1)
80     {
81       switch (opt)
82         {
83         case 'i': interactive = true; break;
84         default: break;
85         }
86     }
87
88
89   if (optind >= argc)
90     interactive = true;
91
92   lua_State *L;
93
94   L = luaL_newstate();
95
96   if (!L)
97     return 1;
98
99   for (int i = 0; libs[i].func; ++i)
100     {
101       lua_pushcfunction(L, libs[i].func);
102       lua_pushstring(L,libs[i].name);
103       lua_call(L, 1, 0);
104     }
105   Lua::init_lua_cap(L);
106   Lua::Lib::run_init(L);
107
108   if (luaL_loadbuffer(L, _binary_ned_lua_start, _binary_ned_lua_end - _binary_ned_lua_start, "@ned.lua"))
109     {
110       printf("Ned: script: ---\n%.*s\n---", (int)(_binary_ned_lua_end - _binary_ned_lua_start), _binary_ned_lua_start);
111       fprintf(stderr, "lua error: %s.\n", lua_tostring(L, -1));
112       lua_pop(L, lua_gettop(L));
113       return 0;
114     }
115
116   if (lua_pcall(L, 0, 1, 0))
117     {
118       fprintf(stderr, "lua error: %s.\n", lua_tostring(L, -1));
119       lua_pop(L, lua_gettop(L));
120       return 0;
121     }
122
123   lua_pop(L, lua_gettop(L));
124
125   for (int c = optind; c < argc; ++c)
126     {
127       printf("Ned: loading file: '%s'\n", argv[c]);
128       int e = luaL_dofile(L, argv[c]);
129       if (e)
130         {
131           char const *error = lua_tostring(L, -1);
132           printf("Ned: ERROR: %s\n", error);
133         }
134       lua_pop(L, lua_gettop(L));
135     }
136
137   lua_gc(L, LUA_GCCOLLECT, 0);
138
139   if (!interactive)
140     return 0;
141
142 #ifndef USE_READLINE
143   fprintf(stderr, "Ned: Interactive mode not compiled in.\n");
144 #else
145   printf("Ned: Interactive mode.\n");
146   const char *cmd;
147   do {
148     cmd = readline((char*)"Ned: ");
149
150     //printf("INPUT: %s\n", cmd);
151
152     if (!cmd)
153       break;
154
155     if (luaL_loadbuffer(L, cmd, strlen(cmd), "argument"))
156       {
157         fprintf(stderr, "lua couldn't parse '%s': %s.\n",
158                 cmd, lua_tostring(L, -1));
159         lua_pop(L, 1);
160       }
161     else
162       {
163         if (lua_pcall(L, 0, 1, 0))
164           {
165             fprintf(stderr, "lua couldn't execute '%s': %s.\n",
166                     cmd, lua_tostring(L, -1));
167             lua_pop(L, 1);
168           }
169         else
170           lua_pop(L, lua_gettop(L));
171       }
172
173   //  cmd = 0;
174   } while (cmd);
175 #endif
176
177   return 0;
178 }