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

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

@ -127,7 +127,7 @@ int fIOthread(void * iodata)
Console & con = core->con; Console & con = core->con;
if(plug_mgr == 0 || core == 0) 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; return 0;
} }
con.print("DFHack is ready. Have a nice day! Type in '?' or 'help' for help.\n"); 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++) for (int j = 0; j < plug->size();j++)
{ {
const PluginCommand & pcmd = (plug->operator[](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 == "" ) else if( command == "" )
@ -186,18 +187,18 @@ int fIOthread(void * iodata)
command_result res = plug_mgr->InvokeCommand(first, parts); command_result res = plug_mgr->InvokeCommand(first, parts);
if(res == CR_NOT_IMPLEMENTED) if(res == CR_NOT_IMPLEMENTED)
{ {
con << "Invalid command." << endl; con.print("Invalid command.\n");
clueless_counter ++; clueless_counter ++;
} }
else if(res == CR_FAILURE) else if(res == CR_FAILURE)
{ {
con << "ERROR!" << endl; con.print("ERROR!\n");
} }
} }
} }
if(clueless_counter == 3) 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; clueless_counter = 0;
} }
} }
@ -233,7 +234,7 @@ bool Core::Init()
p = new DFHack::Process(vif); p = new DFHack::Process(vif);
if (!p->isIdentified()) 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; errorstate = true;
delete p; delete p;
p = NULL; p = NULL;
@ -245,7 +246,7 @@ bool Core::Init()
AccessMutex = SDL_CreateMutex(); AccessMutex = SDL_CreateMutex();
if(!AccessMutex) if(!AccessMutex)
{ {
con << "Mutex creation failed." << std::endl; con.print("Mutex creation failed\n");
errorstate = true; errorstate = true;
return false; return false;
} }
@ -254,7 +255,7 @@ bool Core::Init()
plug_mgr = new PluginManager(this); plug_mgr = new PluginManager(this);
if(!plug_mgr) if(!plug_mgr)
{ {
con << "Failed to create the Plugin Manager." << std::endl; con.print("Failed to create the Plugin Manager.\n");
errorstate = true; errorstate = true;
return false; return false;
} }

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

@ -18,6 +18,16 @@ case "$1" in
gdb ./libs/Dwarf_Fortress $* gdb ./libs/Dwarf_Fortress $*
ret=$? 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 $* ./libs/Dwarf_Fortress $*
ret=$? ret=$?