#include #include "luaconsole.hpp" LuaConsole::LuaConsole() { lua_state_ = lua_open(); clear(); } LuaConsole::~LuaConsole() { lua_close(lua_state_); } void LuaConsole::clear() { raw_input_ = ""; lines_ = 0; lua_expression_ = ""; words_.clear(); syntax_ = ""; action_ = DO_NOTHING; } void LuaConsole::split_words() { words_.clear(); std::string acc; for (char c : raw_input_) { if ((c == ' ')||(c == '\n')) { if (!acc.empty()) { words_.push_back(acc); acc = ""; } } else { acc += c; } } if (!acc.empty()) { words_.push_back(acc); } } void LuaConsole::add(std::string line) { if (action_ != DO_NOTHING) { clear(); } for (int i = 0; i < int(line.size()); i++) { if (line[i] == '\n') line[i] = ' '; } raw_input_ += line; raw_input_ += '\n'; lines_ += 1; char cmd = raw_input_[0]; // All commands are a single character. if ((raw_input_[1] != ' ')&&(raw_input_[1] != '\n')) { action_ = DO_SYNTAX; syntax_ = "Commands are a single character followed by arguments"; return; } // Analyze non-lua commands. if ((cmd != 'r') && (cmd != 'l')) { lua_expression_ = ""; if (lines_ == 1) { action_ = DO_COMMAND; split_words(); } else { action_ = DO_SYNTAX; syntax_ = "slash command has more than one line"; } return; } // Strip the leading punctuation from lua commands. std::string partial; if (cmd == 'r') { partial = std::string("return ") + raw_input_.substr(2); } else { partial = raw_input_.substr(2); } // Analyze lua expressions. int top = lua_gettop(lua_state_); int status = luaL_loadbuffer(lua_state_, partial.c_str(), partial.size(), "=stdin"); if (status == LUA_ERRSYNTAX) { const char *eof = "''"; size_t lmsg; const char *msg = lua_tolstring(lua_state_, -1, &lmsg); const char *tp = msg + lmsg - (sizeof(eof) - 1); if (strstr(msg, eof) == tp) { action_ = DO_NOTHING; } else { action_ = DO_SYNTAX; syntax_ = msg; } } else { action_ = DO_LUA; lua_expression_ = partial; } lua_settop(lua_state_, top); } void LuaConsole::add_stdin() { if (action_ != DO_NOTHING) { clear(); } const int MAXINPUT = 1000; char buf[MAXINPUT]; fputs(raw_input_.empty() ? "> " : ">> ", stdout); fflush(stdout); if (fgets(buf, MAXINPUT, stdin)) { size_t len = strlen(buf); if (len > 0 && buf[len - 1] == '\n') buf[len - 1] = '\0'; add(buf); } }