Fix for a bug in command history queue access. dfhack script can run valgrind.

develop
Petr Mrázek 2011-07-14 08:02:29 +02:00
parent 96153a7b05
commit f2b46274ec
5 changed files with 46 additions and 40 deletions

@ -118,15 +118,17 @@ namespace DFHack
}
Console::Console():std::ostream(0), std::ios(0)
{
d = new Private();
d = 0;
}
Console::~Console()
{
delete d;
if(d)
delete d;
}
bool Console::init(void)
{
d = new Private();
// make our own weird streams so our IO isn't redirected
d->dfout_C = fopen("/dev/tty", "w");
d->stream_o = new duthomhas::stdiobuf(d->dfout_C);
@ -139,7 +141,7 @@ bool Console::shutdown(void)
{
if(d->rawmode)
disable_raw();
*this << std::endl;
print("\n");
}
int Console::print( const char* format, ... )
@ -174,16 +176,13 @@ void Console::clear()
}
else
{
*this << "\033c";
*this << "\033[3J\033[H";
print("\033c\033[3J\033[H");
}
}
void Console::gotoxy(int x, int y)
{
std::ostringstream oss;
oss << "\033[" << y << ";" << x << "H";
*this << oss.str();
print("\033[%d;%dH", y,x);
}
const char * ANSI_CLS = "\033[2J";
@ -231,25 +230,20 @@ const char * getANSIColor(const int c)
void Console::color(int index)
{
*this << getANSIColor(index);
print(getANSIColor(index));
}
void Console::reset_color( void )
{
*this << RESETCOLOR;
print(RESETCOLOR);
}
void Console::cursor(bool enable)
{
if(enable)
{
*this <<"\033[?25h";
}
print("\033[?25h");
else
{
*this <<"\033[?25l";
}
print("\033[?25l");
}
void Console::msleep (unsigned int msec)
@ -339,8 +333,8 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
/* The latest history entry is always our current buffer, that
* initially is just an empty string. */
history_add("");
const std::string empty;
history_add(empty);
if (::write(fd,prompt.c_str(),plen) == -1) return -1;
while(1)
{
@ -374,7 +368,8 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
continue;
}
switch(c) {
switch(c)
{
case 13: /* enter */
d->history.pop_front();
return buffer.size();
@ -516,7 +511,7 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
// push to front, remove from back if we are above maximum. ignore immediate duplicates
void Console::history_add(const std::string & command)
{
if(d->history.front() == command)
if(!d->history.empty() && d->history.front() == command)
return;
d->history.push_front(command);
if(d->history.size() > 100)
@ -527,11 +522,10 @@ int Console::lineedit(const std::string & prompt, std::string & output)
{
output.clear();
int count;
if (d->isUnsupportedTerm() || !isatty(STDIN_FILENO))
{
*this << prompt;
flush();
print(prompt.c_str());
fflush(d->dfout_C);
std::getline(std::cin, output);
return output.size();
}
@ -540,7 +534,7 @@ int Console::lineedit(const std::string & prompt, std::string & output)
if (enable_raw() == -1) return 0;
count = prompt_loop(prompt, output);
disable_raw();
*this << std::endl;
print("\n");
return output.size();
}
}

@ -83,7 +83,7 @@ namespace DFHack
Console::Console():std::ostream(0), std::ios(0)
{
d = new Private();
d = 0;
}
Console::~Console()
@ -92,6 +92,7 @@ Console::~Console()
bool Console::init(void)
{
d = new Private();
int hConHandle;
long lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
@ -267,10 +268,10 @@ int Console::prompt_loop(const std::string & prompt, std::string & buffer)
size_t plen = prompt.size();
size_t pos = 0;
int history_index = 0;
/* The latest history entry is always our current buffer, that
* initially is just an empty string. */
history_add("");
const std::string empty;
history_add(empty);
CONSOLE_SCREEN_BUFFER_INFO inf = { 0 };
GetConsoleScreenBufferInfo(d->console_out, &inf);

@ -127,7 +127,7 @@ int fIOthread(void * iodata)
Console & con = core->con;
if(plug_mgr == 0 || core == 0)
{
con.print("Something horrible happened to the plugin manager in Core's constructor...\n");
con.print("Something horrible happened in Core's constructor...\n");
return 0;
}
con.print("DFHack is ready. Have a nice day! Type in '?' or 'help' for help.\n");
@ -162,9 +162,10 @@ int fIOthread(void * iodata)
for (int j = 0; j < plug->size();j++)
{
const PluginCommand & pcmd = (plug->operator[](j));
con << setw(12) << pcmd.name << "| " << pcmd.description << endl;
con.print("%12s| %s\n",pcmd.name.c_str(), pcmd.description.c_str());
//con << setw(12) << pcmd.name << "| " << pcmd.description << endl;
}
con << endl;
con.print("\n");
}
}
else if( command == "" )
@ -186,18 +187,18 @@ int fIOthread(void * iodata)
command_result res = plug_mgr->InvokeCommand(first, parts);
if(res == CR_NOT_IMPLEMENTED)
{
con << "Invalid command." << endl;
con.print("Invalid command.\n");
clueless_counter ++;
}
else if(res == CR_FAILURE)
{
con << "ERROR!" << endl;
con.print("ERROR!\n");
}
}
}
if(clueless_counter == 3)
{
con << "Do 'help' or '?' for the list of available commands." << endl;
con.print("Do 'help' or '?' for the list of available commands.\n");
clueless_counter = 0;
}
}
@ -233,7 +234,7 @@ bool Core::Init()
p = new DFHack::Process(vif);
if (!p->isIdentified())
{
con << "Couldn't identify this version of DF." << std::endl;
con.print("Couldn't identify this version of DF.\n");
errorstate = true;
delete p;
p = NULL;
@ -245,7 +246,7 @@ bool Core::Init()
AccessMutex = SDL_CreateMutex();
if(!AccessMutex)
{
con << "Mutex creation failed." << std::endl;
con.print("Mutex creation failed\n");
errorstate = true;
return false;
}
@ -254,7 +255,7 @@ bool Core::Init()
plug_mgr = new PluginManager(this);
if(!plug_mgr)
{
con << "Failed to create the Plugin Manager." << std::endl;
con.print("Failed to create the Plugin Manager.\n");
errorstate = true;
return false;
}

@ -81,20 +81,20 @@ Plugin::Plugin(Core * core, const std::string & file)
DFLibrary * plug = OpenPlugin(file.c_str());
if(!plug)
{
con << "Can't load plugin " << filename << endl;
con.print("Can't load plugin %s\n", filename.c_str());
return;
}
const char * (*_PlugName)() =(const char * (*)()) LookupPlugin(plug, "plugin_name");
if(!_PlugName)
{
con << "Plugin " << filename << " has no name." << endl;
con.print("Plugin %s has no name.\n", filename.c_str());
ClosePlugin(plug);
return;
}
plugin_init = (command_result (*)(Core *, std::vector <PluginCommand> &)) LookupPlugin(plug, "plugin_init");
if(!plugin_init)
{
con << "Plugin " << filename << " has no init function." << endl;
con.print("Plugin %s has no init function.\n", filename.c_str());
ClosePlugin(plug);
return;
}

@ -18,6 +18,16 @@ case "$1" in
gdb ./libs/Dwarf_Fortress $*
ret=$?
;;
-h | --helgrind)
shift
valgrind --tool=helgrind --log-file=helgrind.log ./libs/Dwarf_Fortress $*
ret=$?
;;
-v | --valgrind)
shift
valgrind --log-file=valgrind.log ./libs/Dwarf_Fortress $*
ret=$?
;;
*)
./libs/Dwarf_Fortress $*
ret=$?