/** * @brief Back end for the Lua print functionality. */ static int cli_printCore( lua_State *L, int cli_only ) { int n = lua_gettop(L); /* number of arguments */ int i; char buf[LINE_LENGTH]; int p; const char *s; p = 0; lua_getglobal(L, "tostring"); for (i=1; i<=n; i++) { lua_pushvalue(L, -1); /* function to be called */ lua_pushvalue(L, i); /* value to print */ lua_call(L, 1, 1); s = lua_tostring(L, -1); /* get result */ if (s == NULL) return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("print")); if (!cli_only) LOG( "%s", s ); /* Add to console. */ p += snprintf( &buf[p], LINE_LENGTH-p, "%s%s", (i>1) ? " " : "", s ); if (p >= LINE_LENGTH) { cli_addMessage(buf); p = 0; } lua_pop(L, 1); /* pop result */ } /* Add last line if needed. */ cli_addMessage(buf); return 0; }
/** * @brief Initializes the CLI environment. */ int cli_init (void) { /* Already loaded. */ if (cli_state != NULL) return 0; /* Calculate size. */ cli_width = SCREEN_W - 100; cli_height = SCREEN_H - 100; /* Create the state. */ cli_state = nlua_newState(); nlua_loadBasic( cli_state ); nlua_loadStandard( cli_state, 0 ); nlua_loadCLI( cli_state ); luaL_register( cli_state, "_G", cli_methods ); lua_settop( cli_state, 0 ); /* Set the font. */ cli_font = malloc( sizeof(glFont) ); gl_fontInit( cli_font, "dat/mono.ttf", CONSOLE_FONT_SIZE ); /* Clear the buffer. */ memset( cli_buffer, 0, sizeof(cli_buffer) ); /* Put a friendly message at first. */ cli_addMessage( "Welcome to the Lua console!" ); cli_addMessage( "" ); return 0; }
/** * @brief Handles the CLI input. * * @param wid Window recieving the input. * @param unused Unused. */ static void cli_input( unsigned int wid, char *unused ) { (void) unused; int status; char *str; lua_State *L; char buf[LINE_LENGTH]; /* Get the input. */ str = window_getInput( wid, "inpInput" ); /* Ignore useless stuff. */ if ((str == NULL) || (str[0] == '\0')) return; /* Put the message in the console. */ snprintf( buf, LINE_LENGTH, "%s %s", cli_firstline ? "> " : ">>", str ); cli_addMessage( buf ); /* Set up state. */ L = cli_state; /* Load the string. */ lua_pushstring( L, str ); /* Concat string if needed. */ if (!cli_firstline) { lua_pushliteral(L, "\n"); /* add a new line... */ lua_insert(L, -2); /* ...between the two lines */ lua_concat(L, 3); /* join them */ } status = luaL_loadbuffer( L, lua_tostring(L,-1), lua_strlen(L,-1), "=cli" ); /* String isn't proper Lua yet. */ if (status == LUA_ERRSYNTAX) { size_t lmsg; const char *msg = lua_tolstring(L, -1, &lmsg); const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1); if (strstr(msg, LUA_QL("<eof>")) == tp) { /* Pop the loaded buffer. */ lua_pop(L, 1); cli_firstline = 0; } else { /* Real error, spew message and break. */ cli_addMessage( lua_tostring(L, -1) ); lua_settop(L, 0); cli_firstline = 1; } } /* Print results - all went well. */ else if (status == 0) { if (lua_pcall(L, 0, LUA_MULTRET, 0)) cli_addMessage( lua_tostring(L, -1) ); /* Clear stack. */ lua_settop(L, 0); cli_firstline = 1; } /* Clear the box now. */ window_setInput( wid, "inpInput", NULL ); }
/** * @brief Opens the console. */ void cli_open (void) { unsigned int wid; /* Lazy loading. */ if (cli_state == NULL) if (cli_init()) return; /* Make sure main menu isn't open. */ if (menu_isOpen(MENU_MAIN)) return; /* Must not be already open. */ if (window_exists( "Lua Console" )) return; /* Put a friendly message at first. */ if (cli_firstOpen) { char buf[256]; cli_addMessage( "" ); cli_addMessage( "\egWelcome to the Lua console!" ); nsnprintf( buf, sizeof(buf), "\eg "APPNAME" v%s", naev_version(0) ); cli_addMessage( buf ); cli_addMessage( "" ); cli_firstOpen = 0; } /* Create the window. */ wid = window_create( "Lua Console", -1, -1, CLI_WIDTH, CLI_HEIGHT ); /* Window settings. */ window_setAccept( wid, cli_input ); window_setCancel( wid, window_close ); window_handleKeys( wid, cli_keyhandler ); /* Input box. */ window_addInput( wid, 20, 20, CLI_WIDTH-60-BUTTON_WIDTH, BUTTON_HEIGHT, "inpInput", LINE_LENGTH, 1, cli_font ); /* Buttons. */ window_addButton( wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnClose", "Close", window_close ); /* Custom console widget. */ window_addCust( wid, 20, -40, CLI_WIDTH-40, CLI_HEIGHT-80-BUTTON_HEIGHT, "cstConsole", 0, cli_render, NULL, NULL ); /* Cache current height in case the window is resized. */ cli_height = CLI_HEIGHT; }