terom@93: #include "lua_console.h" terom@93: #include "lua_objs.h" terom@93: #include "log.h" terom@93: terom@93: #include terom@93: terom@93: #include terom@93: terom@203: struct lua_console { terom@203: /** The lowlevel line-based console */ terom@203: struct console *console; terom@203: terom@203: /** Our lua state */ terom@203: struct nexus_lua *lua; terom@203: terom@203: /** Coroutine state */ terom@203: struct lua_thread thread; terom@203: }; terom@203: terom@203: /** terom@203: * Line finished execution terom@203: */ terom@205: static void lua_console_on_thread (const error_t *err, void *arg) terom@93: { terom@93: struct lua_console *lc = arg; terom@203: terom@203: if (err) terom@203: // display error message terom@203: console_print(lc->console, error_msg(err)); terom@203: terom@203: // XXX: display return value? terom@203: terom@203: // un-wait console terom@203: console_continue(lc->console); terom@203: } terom@203: terom@203: /** terom@203: * Got a line to exec from the console terom@203: */ terom@203: static enum console_line_status lua_console_on_line (const char *line, void *arg) terom@203: { terom@203: struct lua_console *lc = arg; terom@203: error_t err; terom@205: int ret; terom@93: terom@93: // ignore empty lines and EOF terom@93: if (!line || !(*line)) terom@203: return CONSOLE_CONTINUE; terom@93: terom@203: // exec it in our thread terom@205: if ((ret = lua_thread_start(&lc->thread, line, &err)) < 0) { terom@203: // display error message terom@137: console_print(lc->console, error_msg(&err)); terom@93: terom@203: return CONSOLE_CONTINUE; terom@205: } terom@203: terom@205: // waiting? terom@205: if (ret) terom@205: return CONSOLE_WAIT; terom@205: terom@205: else terom@205: return CONSOLE_CONTINUE; terom@93: } terom@93: terom@170: static void lua_console_on_eof (void *arg) terom@170: { terom@170: struct lua_console *lc = arg; terom@170: terom@170: // exit the process terom@170: nexus_shutdown(lc->lua->nexus); terom@170: } terom@170: terom@213: static void lua_console_on_interrupt (void *arg) terom@213: { terom@213: struct lua_console *lc = arg; terom@213: terom@213: // abort thread so we can _start again terom@213: lua_thread_abort(&lc->thread); terom@213: terom@213: // inform user terom@213: console_print(lc->console, "Execution aborted."); terom@213: terom@213: // accept input terom@213: console_continue(lc->console); terom@213: } terom@213: terom@93: static struct console_callbacks _console_callbacks = { terom@213: .on_line = lua_console_on_line, terom@213: .on_eof = lua_console_on_eof, terom@213: .on_interrupt = lua_console_on_interrupt, terom@93: }; terom@93: terom@105: err_t lua_console_create (struct lua_console **lc_ptr, struct console *console, struct nexus_lua *lua, struct error_info *err) terom@93: { terom@93: struct lua_console *lc; terom@93: terom@93: // allocate terom@93: if ((lc = calloc(1, sizeof(*lc))) == NULL) terom@93: return SET_ERROR(err, ERR_CALLOC); terom@93: terom@93: // store terom@93: lc->console = console; terom@105: lc->lua = lua; terom@93: terom@93: // set our console callbacks terom@93: console_set_callbacks(console, &_console_callbacks, lc); terom@93: terom@203: // init thread terom@203: lua_thread_init(&lc->thread, lua, lua_console_on_thread, lc); terom@203: terom@93: // ok terom@93: *lc_ptr = lc; terom@93: terom@93: return SUCCESS; terom@93: } terom@93: terom@93: void lua_console_destroy (struct lua_console *lc) terom@93: { terom@105: // the console terom@93: console_destroy(lc->console); terom@93: terom@93: free(lc); terom@93: }