diff --git a/library/Console-posix.cpp b/library/Console-posix.cpp index a06008cba..6602b0d0b 100644 --- a/library/Console-posix.cpp +++ b/library/Console-posix.cpp @@ -423,13 +423,13 @@ namespace DFHack int count; if (enable_raw() == -1) return 0; if(state == con_lineedit) - return -1; + return Console::FAILURE; state = con_lineedit; count = prompt_loop(lock,ch); state = con_unclaimed; disable_raw(); print("\n"); - if(count != -1) + if(count > Console::FAILURE) { output = toLocaleMB(raw_buffer); } @@ -441,9 +441,9 @@ namespace DFHack struct termios raw; if (!supported_terminal) - return -1; + return Console::FAILURE; if (tcgetattr(STDIN_FILENO,&orig_termios) == -1) - return -1; + return Console::FAILURE; raw = orig_termios; //modify the original mode // input modes: no break, no CR to NL, no parity check, no strip char, @@ -465,7 +465,7 @@ namespace DFHack raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0;// 1 byte, no timer // put terminal in raw mode if (tcsetattr(STDIN_FILENO, TCSADRAIN, &raw) < 0) - return -1; + return Console::FAILURE; rawmode = 1; return 0; } @@ -518,7 +518,8 @@ namespace DFHack * initially is just an empty string. */ const std::string empty; history.add(empty); - if (::write(fd,prompt.c_str(),prompt.size()) == -1) return -1; + if (::write(fd,prompt.c_str(),prompt.size()) == -1) + return Console::FAILURE; while(1) { unsigned char c; @@ -528,7 +529,7 @@ namespace DFHack if(!read_char(c)) { lock->lock(); - return -2; + return Console::SHUTDOWN; } lock->lock(); /* Only autocomplete when the callback is set. It returns < 0 when @@ -561,8 +562,7 @@ namespace DFHack history.remove(); return raw_buffer.size(); case 3: // ctrl-c - errno = EAGAIN; - return -1; + return Console::RETRY; case 127: // backspace case 8: // ctrl-h if (raw_cursor > 0 && raw_buffer.size() > 0) @@ -577,7 +577,7 @@ namespace DFHack if (!read_char(seq[0])) { lock->lock(); - return -2; + return Console::SHUTDOWN; } lock->lock(); if (seq[0] == 'b') @@ -593,7 +593,7 @@ namespace DFHack if (!read_char(seq[1])) { lock->lock(); - return -2; + return Console::SHUTDOWN; } if (seq[1] == 'D') { @@ -658,7 +658,7 @@ namespace DFHack if(!read_char(seq2)) { lock->lock(); - return -2; + return Console::SHUTDOWN; } lock->lock(); if (seq[1] == '3' && seq2 == '~' ) @@ -674,7 +674,7 @@ namespace DFHack if (!read_char(seq3[0]) || !read_char(seq3[1])) { lock->lock(); - return -2; + return Console::SHUTDOWN; } if (seq2 == ';') { @@ -747,9 +747,9 @@ namespace DFHack // character starting from the first bye already red while ((sz = mbrtoc32(&c32,&mb[count-1],1, &state)) < 0) { if (sz == -1 || sz == -3) - return -1; /* mbrtoc32 error (not valid utf-32 character */ + return Console::FAILURE; /* mbrtoc32 error (not valid utf-32 character */ if(!read_char(c)) - return -2; + return Console::SHUTDOWN; mb[count++] = c; } if (raw_buffer.size() == size_t(raw_cursor)) @@ -760,7 +760,8 @@ namespace DFHack { /* Avoid a full update of the line in the * trivial case. */ - if (::write(fd,mb,count) == -1) return -1; + if (::write(fd,mb,count) == -1) + return Console::FAILURE; } else { @@ -888,7 +889,7 @@ void Console::add_text(color_value color, const std::string &text) int Console::get_columns(void) { lock_guard g(*wlock); - int ret = -1; + int ret = Console::FAILURE; if(inited) ret = d->get_columns(); return ret; @@ -897,7 +898,7 @@ int Console::get_columns(void) int Console::get_rows(void) { lock_guard g(*wlock); - int ret = -1; + int ret = Console::FAILURE; if(inited) ret = d->get_rows(); return ret; @@ -927,10 +928,10 @@ void Console::cursor(bool enable) int Console::lineedit(const std::string & prompt, std::string & output, CommandHistory & ch) { lock_guard g(*wlock); - int ret = -2; + int ret = Console::SHUTDOWN; if(inited) { ret = d->lineedit(prompt,output,wlock,ch); - if (ret == -2) { + if (ret == Console::SHUTDOWN) { // kill the thing if(d->rawmode) d->disable_raw(); diff --git a/library/Console-windows.cpp b/library/Console-windows.cpp index f3771f4ff..7d3272c93 100644 --- a/library/Console-windows.cpp +++ b/library/Console-windows.cpp @@ -287,7 +287,7 @@ namespace DFHack lock->unlock(); if (ReadConsoleInputA(console_in, &rec, 1, &count) != 0) { lock->lock(); - return -2; + return Console::SHUTDOWN; } lock->lock(); if (rec.EventType != KEY_EVENT || !rec.Event.KeyEvent.bKeyDown) @@ -382,7 +382,7 @@ namespace DFHack state = con_lineedit; this->prompt = prompt; count = prompt_loop(lock, ch); - if(count != -1) + if(count > Console::FAILURE) output = raw_buffer; state = con_unclaimed; print("\n"); @@ -591,7 +591,7 @@ void Console::cursor(bool enable) int Console::lineedit(const std::string & prompt, std::string & output, CommandHistory & ch) { wlock->lock(); - int ret = -2; + int ret = Console::SHUTDOWN; if(inited) ret = d->lineedit(prompt,output,wlock,ch); wlock->unlock(); diff --git a/library/Core.cpp b/library/Core.cpp index 463175e0f..1e0a882b5 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1421,13 +1421,15 @@ void fIOthread(void * iodata) while (true) { string command = ""; - int ret = con.lineedit("[DFHack]# ",command, main_history); - if(ret == -2) + int ret; + while ((ret = con.lineedit("[DFHack]# ",command, main_history)) + == Console::RETRY); + if(ret == Console::SHUTDOWN) { cerr << "Console is shutting down properly." << endl; return; } - else if(ret == -1) + else if(ret == Console::FAILURE) { cerr << "Console caught an unspecified error." << endl; continue; diff --git a/library/LuaTools.cpp b/library/LuaTools.cpp index 8e05fbe22..3ac52bf45 100644 --- a/library/LuaTools.cpp +++ b/library/LuaTools.cpp @@ -293,10 +293,13 @@ static int dfhack_lineedit_sync(lua_State *S, Console *pstream) std::string ret; int rv = pstream->lineedit(prompt, ret, hist); + if (rv == Console::RETRY) + rv = 0; /* return empty string to lua */ + if (rv < 0) { lua_pushnil(S); - if (rv == -2) + if (rv == Console::SHUTDOWN) lua_pushstring(S, "shutdown requested"); else lua_pushstring(S, "input error"); @@ -1061,9 +1064,9 @@ bool DFHack::Lua::RunCoreQueryLoop(color_ostream &out, lua_State *state, prompt = ">> "; std::string curline; - rv = con.lineedit(prompt,curline,hist); - if (rv < 0) { - rv = rv == -2 ? LUA_OK : LUA_ERRRUN; + while((rv = con.lineedit(prompt,curline,hist)) == Console::RETRY); + if (rv <= Console::FAILURE) { + rv = rv == Console::SHUTDOWN ? LUA_OK : LUA_ERRRUN; break; } hist.add(curline); diff --git a/library/include/Console.h b/library/include/Console.h index 12ce94488..0517704d4 100644 --- a/library/include/Console.h +++ b/library/include/Console.h @@ -153,6 +153,12 @@ namespace DFHack int get_rows(void); /// beep. maybe? //void beep (void); + //! \defgroup lineedit_return_values Possible errors from lineedit + //! \{ + static constexpr int FAILURE = -1; + static constexpr int SHUTDOWN = -2; + static constexpr int RETRY = -3; + //! \} /// A simple line edit (raw mode) int lineedit(const std::string& prompt, std::string& output, CommandHistory & history ); bool isInited (void) { return inited; }; diff --git a/plugins/Brushes.h b/plugins/Brushes.h index 0ef9c147e..14a4188e7 100644 --- a/plugins/Brushes.h +++ b/plugins/Brushes.h @@ -237,8 +237,10 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out, str.str(""); str << "Set range width <" << width << "> "; - if ((rv = con.lineedit(str.str(), command, hist)) < 0) - return rv == -2 ? CR_OK : CR_FAILURE; + while ((rv = con.lineedit(str.str(), command, hist)) + == Console::RETRY); + if (rv <= Console::FAILURE) + return rv == Console::FAILURE ? CR_FAILURE : CR_FAILURE; hist.add(command); newWidth = command.empty() ? width : atoi(command.c_str()); } else { @@ -252,8 +254,10 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out, str.str(""); str << "Set range height <" << height << "> "; - if ((rv = con.lineedit(str.str(), command, hist)) < 0) - return rv == -2 ? CR_OK : CR_FAILURE; + while ((rv = con.lineedit(str.str(), command, hist)) + == Console::RETRY); + if (rv <= Console::FAILURE) + return rv == Console::FAILURE ? CR_FAILURE : CR_OK; hist.add(command); newHeight = command.empty() ? height : atoi(command.c_str()); } else { @@ -267,8 +271,10 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out, str.str(""); str << "Set range z-levels <" << zLevels << "> "; - if ((rv = con.lineedit(str.str(), command, hist)) < 0) - return rv == -2 ? CR_OK : CR_FAILURE; + while ((rv = con.lineedit(str.str(), command, hist)) + == Console::RETRY); + if (rv <= Console::FAILURE) + return rv == Console::FAILURE ? CR_FAILURE : CR_OK; hist.add(command); newZLevels = command.empty() ? zLevels : atoi(command.c_str()); } else { diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp index 12e92a573..5dd64812f 100644 --- a/plugins/liquids.cpp +++ b/plugins/liquids.cpp @@ -189,8 +189,10 @@ command_result df_liquids (color_ostream &out_, vector & parameters) print_prompt(str, cur_mode); str << "# "; int rv; - if((rv = out.lineedit(str.str(),input,liquids_hist)) < 0) - return rv == -2 ? CR_OK : CR_FAILURE; + while ((rv = out.lineedit(str.str(),input,liquids_hist)) + == Console::RETRY); + if (rv <= Console::FAILURE) + return rv == Console::FAILURE ? CR_FAILURE : CR_OK; liquids_hist.add(input); commands.clear(); diff --git a/plugins/mode.cpp b/plugins/mode.cpp index 5258e2007..5e58c50a0 100644 --- a/plugins/mode.cpp +++ b/plugins/mode.cpp @@ -140,9 +140,10 @@ command_result mode (color_ostream &out_, vector & parameters) string selected; input_again: CommandHistory hist; - rv = out.lineedit("Enter new mode: ",selected, hist); - if(rv < 0 || selected == "c") - return rv == -2 ? CR_OK : CR_FAILURE; + while((rv = out.lineedit("Enter new mode: ",selected, hist)) + == Console::RETRY); + if(rv <= Console::FAILURE || selected == "c") + return rv == Console::FAILURE ? CR_FAILURE : CR_OK; const char * start = selected.c_str(); char * end = 0; select = strtol(start, &end, 10); @@ -179,14 +180,16 @@ command_result mode (color_ostream &out_, vector & parameters) { CommandHistory hist; string selected; - rv = out.lineedit("Enter new game mode number (c for exit): ",selected, hist); - if(rv < 0 || selected == "c") - return rv == -2 ? CR_OK : CR_FAILURE; + while ((rv = out.lineedit("Enter new game mode number (c for exit): ",selected, hist)) + == Console::RETRY); + if(rv <= Console::FAILURE || selected == "c") + return rv == Console::FAILURE ? CR_FAILURE : CR_OK; const char * start = selected.c_str(); gm.g_mode = (GameMode) strtol(start, 0, 10); - rv = out.lineedit("Enter new game type number (c for exit): ",selected, hist); - if(rv < 0 || selected == "c") - return rv == -2 ? CR_OK : CR_FAILURE; + while((rv = out.lineedit("Enter new game type number (c for exit): ",selected, hist)) + == Console::RETRY); + if(rv <= Console::FAILURE || selected == "c") + return rv == Console::FAILURE ? CR_FAILURE : CR_OK; start = selected.c_str(); gm.g_type = (GameType) strtol(start, 0, 10); } diff --git a/plugins/tiletypes.cpp b/plugins/tiletypes.cpp index 1e3362b0b..31ff096f1 100644 --- a/plugins/tiletypes.cpp +++ b/plugins/tiletypes.cpp @@ -986,8 +986,10 @@ command_result df_tiletypes (color_ostream &out_, vector & parameters) std::string input = ""; int rv = 0; - if ((rv = out.lineedit("tiletypes> ",input,tiletypes_hist)) < 0) - return rv == -2 ? CR_OK : CR_FAILURE; + while ((rv = out.lineedit("tiletypes> ",input,tiletypes_hist)) + == Console::RETRY); + if (rv <= Console::FAILURE) + return rv == Console::FAILURE ? CR_FAILURE : CR_OK; tiletypes_hist.add(input); commands.clear();