X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcommandinterpreter.cpp;h=367ac17f9651684e98113d472140cc1b23e4a4d2;hb=de6ac03ffc36843bbbb0d496007b3046a4422ee1;hp=c684979bae2061b49f9fddd06a8cead8c381e9d6;hpb=ca49785159e6a7cfd2d999a99041fa1567575a24;p=gldbg.git diff --git a/source/commandinterpreter.cpp b/source/commandinterpreter.cpp index c684979..367ac17 100644 --- a/source/commandinterpreter.cpp +++ b/source/commandinterpreter.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of gldbg -Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions Distributed under the GPL */ @@ -23,65 +23,66 @@ using namespace Msp; CommandInterpreter::CommandInterpreter(GlDbg &d): gldbg(d) { - commands["help"] = Command(&CommandInterpreter::cmd_help, - "Provides help on commands", - "help\n" - " Displays a list of commands\n\n" - "help COMMAND\n" - " Gives detailed information on a command\n"); - commands["exit"] = Command(&CommandInterpreter::cmd_exit, - "Ends the debugging session"); - - commands["run"] = Command(&CommandInterpreter::cmd_run, - "Starts the program"); - commands["continue"] = Command(&CommandInterpreter::cmd_continue, - "Resumes program execution"); - commands["kill"] = Command(&CommandInterpreter::cmd_kill, - "Terminates the program immediately"); - commands["signal"] = Command(&CommandInterpreter::cmd_signal, - "Resumes execution with a signal", - "signal NUM\n" - "signal NAME\n" - " Sends the signal identified by NUM or NAME to the program and resumes\n" - " execution. Currently recognized signal names are HUP, INT, TERM, SEGV\n" - " and TERM.\n"); - - commands["trace"] = Command(&CommandInterpreter::cmd_trace, - "Traces GL function calls", - "trace\n" - " Send trace output to stdout.\n" - "trace FILE\n" - " Send trace output to FILE (- for stdout).\n\n" - "trace {off|on}\n" - " Temporarily suspend or resume trace without closing the file.\n\n" - "trace end\n" - " Terminate trace, closing the file.\n"); - - commands["profile"] = Command(&CommandInterpreter::cmd_profile, - "Profiles GL usage and performance", - "profile {on|off}\n" - " Enables or disables profiling\n"); - - commands["state"] = Command(&CommandInterpreter::cmd_state, - "Inspects general GL state", - "state vertex\n" - " Print current vertex attributes\n\n" - "state bind\n" - " Show current bindings\n"); - - commands["texture"] = Command(&CommandInterpreter::cmd_texture, - "Inspect texture state", - "texture\n" - " Lists texture objects\n\n" - "texture ID\n" - " Print information about a texture object\n"); - - commands["buffer"] = Command(&CommandInterpreter::cmd_buffer, - "Inspect buffer object state", - "buffer\n" - " Lists buffer objects\n\n" - "buffer ID\n" - " Print information about a buffer object\n"); + register_command("help", this, &CommandInterpreter::cmd_help) + .set_help("Provides help on commands", + "help\n" + " Displays a list of commands\n\n" + "help COMMAND\n" + " Gives detailed information on a command\n"); + register_command("exit", this, &CommandInterpreter::cmd_exit) + .set_help("Ends the debugging session"); + commands["quit"] = new CommandAlias(commands["exit"]); + + register_command("run", this, &CommandInterpreter::cmd_run) + .set_help("Starts the program"); + register_command("continue", this, &CommandInterpreter::cmd_continue) + .set_help("Resumes program execution"); + register_command("kill", this, &CommandInterpreter::cmd_kill) + .set_help("Terminates the program immediately"); + register_command("signal", this, &CommandInterpreter::cmd_signal) + .set_help("Resumes execution with a signal", + "signal NUM\n" + "signal NAME\n" + " Sends the signal identified by NUM or NAME to the program and resumes\n" + " execution. Currently recognized signal names are HUP, INT, TERM, SEGV\n" + " and TERM.\n"); + + register_command("trace", this, &CommandInterpreter::cmd_trace) + .set_help("Traces GL function calls", + "trace\n" + " Send trace output to stdout.\n\n" + "trace FILE\n" + " Send trace output to FILE (- for stdout).\n\n" + "trace {off|on}\n" + " Temporarily suspend or resume trace without closing the file.\n\n" + "trace end\n" + " Terminate trace, closing the file.\n"); + + register_command("profile", this, &CommandInterpreter::cmd_profile) + .set_help("Profiles GL usage and performance", + "profile {on|off}\n" + " Enables or disables profiling\n"); + + register_command("state", this, &CommandInterpreter::cmd_state) + .set_help("Inspects general GL state", + "state vertex\n" + " Print current vertex attributes\n\n" + "state bind\n" + " Show current bindings\n"); + + register_command("texture", this, &CommandInterpreter::cmd_texture) + .set_help("Inspect texture state", + "texture\n" + " Lists texture objects\n\n" + "texture ID\n" + " Print information about a texture object\n"); + + register_command("buffer", this, &CommandInterpreter::cmd_buffer) + .set_help("Inspect buffer object state", + "buffer\n" + " Lists buffer objects\n\n" + "buffer ID\n" + " Print information about a buffer object\n"); } void CommandInterpreter::execute(const string &cmd) @@ -102,24 +103,30 @@ void CommandInterpreter::execute(const string &cmd) if(space!=string::npos) args = cmd.substr(space+1); - (this->*(i->second.func))(args); + i->second->execute(args); } void CommandInterpreter::cmd_help(const string &args) { if(args.empty()) { - for(map::const_iterator i=commands.begin(); i!=commands.end(); ++i) - IO::print("%-10s : %s\n", i->first, i->second.description); + for(CommandMap::const_iterator i=commands.begin(); i!=commands.end(); ++i) + if(!dynamic_cast(i->second)) + IO::print("%-10s : %s\n", i->first, i->second->get_description()); } else { - map::const_iterator i = commands.find(args); + CommandMap::const_iterator i = commands.find(args); if(i==commands.end()) throw KeyError("Unknown command", args); - IO::print("%s : %s\n", i->first, i->second.description); - if(!i->second.help.empty()) - IO::print("\n%s", i->second.help); + + const Command *cmd = i->second; + while(const CommandAlias *alias = dynamic_cast(cmd)) + cmd = alias->get_target(); + + IO::print("%s : %s\n", i->first, cmd->get_description()); + if(!cmd->get_help().empty()) + IO::print("\n%s", cmd->get_help()); } } @@ -304,21 +311,109 @@ void CommandInterpreter::cmd_buffer(const string &args) IO::print("Buffer %d:\n", id); IO::print(" Size: %d bytes\n", buf.size); IO::print(" Usage: %s\n", describe_enum(buf.usage, "")); + if(buf.content.stride) + { + IO::print(" Stride: %d bytes\n", buf.content.stride); + + IO::print(" Arrays:\n"); + const vector &arrays = buf.content.arrays; + for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) + { + if(i->kind) + IO::print(" %2d: %s, %d %s\n", i->offset, + describe_enum(i->kind, ""), i->size, describe_enum(i->type, "DataType")); + else + IO::print(" %2d: Attrib %d, %d %s\n", i->offset, + i->index, i->size, describe_enum(i->type, "DataType")); + } + + IO::print(" Data:\n"); + string header; + for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) + { + if(!header.empty()) + header += " | "; + + string label; + if(i->kind==GL_VERTEX_ARRAY) + label = "Vertex"; + else if(i->kind==GL_NORMAL_ARRAY) + label = "Normal"; + else if(i->kind==GL_COLOR_ARRAY) + label = "Color"; + else if(i->kind==GL_TEXTURE_COORD_ARRAY) + { + if(i->size==1) + label = "TexC"; + else + label = "TexCoord"; + } + else if(!i->kind) + { + if(i->size==1) + label = format("A %d", i->index); + else + label = format("Attrib %d", i->index); + } + + unsigned width = i->size; + if(i->type==GL_FLOAT) + width *= 5; + else if(i->type==GL_UNSIGNED_BYTE) + width *= 3; + width += i->size-1; + + header.append((width-label.size())/2, ' '); + header += label; + header.append((width-label.size()+1)/2, ' '); + } + IO::print(" %s\n", header); + + unsigned n_verts = buf.size/buf.content.stride; + for(unsigned i=0; i::const_iterator j=arrays.begin(); j!=arrays.end(); ++j) + { + if(!line.empty()) + line += " |"; + + const char *base = vertex+j->offset; + for(unsigned k=0; ksize; ++k) + { + if(j->type==GL_FLOAT) + line += format(" %5.2f", *(reinterpret_cast(base)+k)); + else if(j->type==GL_UNSIGNED_BYTE) + line += format(" %3u", *(reinterpret_cast(base)+k)); + } + } + + IO::print("%3d:%s\n", i, line); + } + } } } -CommandInterpreter::Command::Command(): - func(0) -{ } +void CommandInterpreter::Command::set_help(const string &d) +{ + description = d; +} + +void CommandInterpreter::Command::set_help(const string &d, const string &h) +{ + description = d; + help = h; +} -CommandInterpreter::Command::Command(Func f, const string &d): - func(f), - description(d) -{ } -CommandInterpreter::Command::Command(Func f, const string &d, const string &h): - func(f), - description(d), - help(h) +CommandInterpreter::CommandAlias::CommandAlias(Command *t): + target(t) { } + +void CommandInterpreter::CommandAlias::execute(const string &a) +{ + target->execute(a); +}