Checke Console::lineedit error return values

Console::lineedit can return -1 to indicate input error and -2 to
indicate the program is closing. But most users don't check possible
unusual return values which can lead to exit hang.
develop
Pauli 2018-06-21 16:57:36 +03:00
parent 84b1361387
commit 1fc37f8ddc
6 changed files with 51 additions and 35 deletions

@ -283,9 +283,6 @@ static int lua_dfhack_is_interactive(lua_State *S)
static int dfhack_lineedit_sync(lua_State *S, Console *pstream)
{
if (!pstream)
return 2;
const char *prompt = luaL_optstring(S, 1, ">> ");
const char *hfile = luaL_optstring(S, 2, NULL);
@ -299,6 +296,9 @@ static int dfhack_lineedit_sync(lua_State *S, Console *pstream)
if (rv < 0)
{
lua_pushnil(S);
if (rv == -2)
lua_pushstring(S, "shutdown requested");
else
lua_pushstring(S, "input error");
return 2;
}
@ -333,8 +333,11 @@ static int dfhack_lineedit(lua_State *S)
lua_settop(S, 2);
Console *pstream = get_console(S);
if (!pstream)
if (!pstream) {
lua_pushnil(S);
lua_pushstring(S, "no console");
return 2;
}
lua_rawgetp(S, LUA_REGISTRYINDEX, &DFHACK_QUERY_COROTABLE_TOKEN);
lua_rawgetp(S, -1, S);
@ -1058,7 +1061,11 @@ bool DFHack::Lua::RunCoreQueryLoop(color_ostream &out, lua_State *state,
prompt = ">> ";
std::string curline;
con.lineedit(prompt,curline,hist);
rv = con.lineedit(prompt,curline,hist);
if (rv < 0) {
rv = rv == -2 ? LUA_OK : LUA_ERRRUN;
break;
}
hist.add(curline);
{

@ -505,9 +505,10 @@ function prompt_yes_no(msg,default)
prompt = prompt..' (y/n)[n]: '
end
while true do
local rv = dfhack.lineedit(prompt)
if rv then
if string.match(rv,'^[Yy]') then
local rv,err = dfhack.lineedit(prompt)
if not rv then
qerror(err);
elseif string.match(rv,'^[Yy]') then
return true
elseif string.match(rv,'^[Nn]') then
return false
@ -518,13 +519,15 @@ function prompt_yes_no(msg,default)
end
end
end
end
-- Ask for input with check function
function prompt_input(prompt,check,quit_str)
quit_str = quit_str or '~~~'
while true do
local rv = dfhack.lineedit(prompt)
local rv,err = dfhack.lineedit(prompt)
if not rv then
qerror(err);
end
if rv == quit_str then
qerror('User abort')
end

@ -214,7 +214,7 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out,
bool hasConsole = true)
{
using namespace DFHack;
int newWidth = 0, newHeight = 0, newZLevels = 0;
int newWidth = 0, newHeight = 0, newZLevels = 0, rv = 0;
if (end > start + 1)
{
@ -237,7 +237,8 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out,
str.str("");
str << "Set range width <" << width << "> ";
con.lineedit(str.str(), command, hist);
if ((rv = con.lineedit(str.str(), command, hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
hist.add(command);
newWidth = command.empty() ? width : atoi(command.c_str());
} else {
@ -251,7 +252,8 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out,
str.str("");
str << "Set range height <" << height << "> ";
con.lineedit(str.str(), command, hist);
if ((rv = con.lineedit(str.str(), command, hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
hist.add(command);
newHeight = command.empty() ? height : atoi(command.c_str());
} else {
@ -265,7 +267,8 @@ DFHack::command_result parseRectangle(DFHack::color_ostream & out,
str.str("");
str << "Set range z-levels <" << zLevels << "> ";
con.lineedit(str.str(), command, hist);
if ((rv = con.lineedit(str.str(), command, hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
hist.add(command);
newZLevels = command.empty() ? zLevels : atoi(command.c_str());
} else {

@ -188,8 +188,9 @@ command_result df_liquids (color_ostream &out_, vector <string> & parameters)
std::stringstream str;
print_prompt(str, cur_mode);
str << "# ";
if(out.lineedit(str.str(),input,liquids_hist) == -1)
return CR_FAILURE;
int rv;
if((rv = out.lineedit(str.str(),input,liquids_hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
liquids_hist.add(input);
commands.clear();

@ -96,6 +96,7 @@ command_result mode (color_ostream &out_, vector <string> & parameters)
string command = "";
bool set = false;
bool abuse = false;
int rv = 0;
t_gamemodes gm;
for(auto iter = parameters.begin(); iter != parameters.end(); iter++)
{
@ -139,9 +140,9 @@ command_result mode (color_ostream &out_, vector <string> & parameters)
string selected;
input_again:
CommandHistory hist;
out.lineedit("Enter new mode: ",selected, hist);
if(selected == "c")
return CR_OK;
rv = out.lineedit("Enter new mode: ",selected, hist);
if(rv < 0 || selected == "c")
return rv == -2 ? CR_OK : CR_FAILURE;
const char * start = selected.c_str();
char * end = 0;
select = strtol(start, &end, 10);
@ -178,14 +179,14 @@ command_result mode (color_ostream &out_, vector <string> & parameters)
{
CommandHistory hist;
string selected;
out.lineedit("Enter new game mode number (c for exit): ",selected, hist);
if(selected == "c")
return CR_OK;
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;
const char * start = selected.c_str();
gm.g_mode = (GameMode) strtol(start, 0, 10);
out.lineedit("Enter new game type number (c for exit): ",selected, hist);
if(selected == "c")
return CR_OK;
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;
start = selected.c_str();
gm.g_type = (GameType) strtol(start, 0, 10);
}

@ -984,9 +984,10 @@ command_result df_tiletypes (color_ostream &out_, vector <string> & parameters)
printState(out);
std::string input = "";
int rv = 0;
if (out.lineedit("tiletypes> ",input,tiletypes_hist) == -1)
return CR_FAILURE;
if ((rv = out.lineedit("tiletypes> ",input,tiletypes_hist)) < 0)
return rv == -2 ? CR_OK : CR_FAILURE;
tiletypes_hist.add(input);
commands.clear();