1 #include "lua_console.h" |
|
2 #include "lua_objs.h" |
|
3 #include "log.h" |
|
4 |
|
5 #include <stdlib.h> |
|
6 |
|
7 #include <lua5.1/lauxlib.h> |
|
8 |
|
9 struct lua_console { |
|
10 /** The lowlevel line-based console */ |
|
11 struct console *console; |
|
12 |
|
13 /** Our lua state */ |
|
14 struct nexus_lua *lua; |
|
15 |
|
16 /** Coroutine state */ |
|
17 struct lua_thread thread; |
|
18 }; |
|
19 |
|
20 /** |
|
21 * Line finished execution |
|
22 */ |
|
23 static void lua_console_on_thread (const error_t *err, void *arg) |
|
24 { |
|
25 struct lua_console *lc = arg; |
|
26 |
|
27 if (err) |
|
28 // display error message |
|
29 console_print(lc->console, error_msg(err)); |
|
30 |
|
31 // XXX: display return value? |
|
32 |
|
33 // un-wait console |
|
34 console_continue(lc->console); |
|
35 } |
|
36 |
|
37 /** |
|
38 * Got a line to exec from the console |
|
39 */ |
|
40 static enum console_line_status lua_console_on_line (const char *line, void *arg) |
|
41 { |
|
42 struct lua_console *lc = arg; |
|
43 error_t err; |
|
44 int ret; |
|
45 |
|
46 // ignore empty lines and EOF |
|
47 if (!line || !(*line)) |
|
48 return CONSOLE_CONTINUE; |
|
49 |
|
50 // exec it in our thread |
|
51 if ((ret = lua_thread_start(&lc->thread, line, &err)) < 0) { |
|
52 // display error message |
|
53 console_print(lc->console, error_msg(&err)); |
|
54 |
|
55 return CONSOLE_CONTINUE; |
|
56 } |
|
57 |
|
58 // waiting? |
|
59 if (ret) |
|
60 return CONSOLE_WAIT; |
|
61 |
|
62 else |
|
63 return CONSOLE_CONTINUE; |
|
64 } |
|
65 |
|
66 static void lua_console_on_eof (void *arg) |
|
67 { |
|
68 struct lua_console *lc = arg; |
|
69 |
|
70 // exit the process |
|
71 nexus_shutdown(lc->lua->nexus); |
|
72 } |
|
73 |
|
74 static void lua_console_on_interrupt (void *arg) |
|
75 { |
|
76 struct lua_console *lc = arg; |
|
77 |
|
78 // abort thread so we can _start again |
|
79 lua_thread_abort(&lc->thread); |
|
80 |
|
81 // inform user |
|
82 console_print(lc->console, "Execution aborted."); |
|
83 |
|
84 // accept input |
|
85 console_continue(lc->console); |
|
86 } |
|
87 |
|
88 static struct console_callbacks _console_callbacks = { |
|
89 .on_line = lua_console_on_line, |
|
90 .on_eof = lua_console_on_eof, |
|
91 .on_interrupt = lua_console_on_interrupt, |
|
92 }; |
|
93 |
|
94 err_t lua_console_create (struct lua_console **lc_ptr, struct console *console, struct nexus_lua *lua, error_t *err) |
|
95 { |
|
96 struct lua_console *lc; |
|
97 |
|
98 // allocate |
|
99 if ((lc = calloc(1, sizeof(*lc))) == NULL) |
|
100 return SET_ERROR(err, ERR_CALLOC); |
|
101 |
|
102 // store |
|
103 lc->console = console; |
|
104 lc->lua = lua; |
|
105 |
|
106 // set our console callbacks |
|
107 console_set_callbacks(console, &_console_callbacks, lc); |
|
108 |
|
109 // init thread |
|
110 lua_thread_init(&lc->thread, lua, lua_console_on_thread, lc); |
|
111 |
|
112 // ok |
|
113 *lc_ptr = lc; |
|
114 |
|
115 return SUCCESS; |
|
116 } |
|
117 |
|
118 void lua_console_destroy (struct lua_console *lc) |
|
119 { |
|
120 // the console |
|
121 console_destroy(lc->console); |
|
122 |
|
123 free(lc); |
|
124 } |
|