Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development
Custom Watch Script Pluggins
yop:
And then we could provide ready to use scrips for various APIs that we use. It's going to be beautiful :)
mandrav:
Implemented it in GDB :lol:
I will have to study CDB a little more before I can implement it there too...
I have not committed it yet because I was in the middle of some other debugger changes. I will finish them all and then commit.
Here's the script that adds wxString support in GDB:
--- Code: (cpp) ---////////////////////////////////////////////////////////////////////////////////
// Parses GDB's output of unicode wxString and turns it to human-readable
////////////////////////////////////////////////////////////////////////////////
//
// Example input:
// {38 '&', 69 'E', 110 'n', 97 'a', 98 'b', 108 'l', 101 'e'}
//
// Example output:
// "&Enable"
////////////////////////////////////////////////////////////////////////////////
// Entry point for testing.
// This is here only for testing the parsing function inside the IDE (while writing it).
// It is *not* used when the script runs in the debugger...
// So, it can safely be removed.
int main()
{
wxString r;
GDB_ParseWXString("{38 '&', 69 'E', 110 'n', 97 'a', 98 'b', 108 'l', 101 'e'}", r);
Log(r);
return 0;
}
void RegisterTypes(DebuggerDriver@ driver)
{
driver.RegisterType(
// The type's name (must be unique, the debugger driver won't accept duplicates).
"wxString",
// Regular expression for type matching.
"[^[:alnum:]_]*wxString[^[:alnum:]_]*",
// Parser function's name (defined below).
"GDB_ParseWXString",
// Define the print function body (this will become a GDB function named print_wxstring).
// Note that we 're using the m_pchData member of wxString to access
// its actual data...
// Also note that we 'll be printing at most 100 chars, i.e. we 're setting a limit.
"output /c (*$arg0.m_pchData)@(($slen=(unsigned int)$arg0.Len())>100?100:$slen)"
);
}
// This function parses GDB's output.
// When it returns, the "result" argument contains the parsing result.
void GDB_ParseWXString(const wxString& in a_str, wxString& out result)
{
result = "\"";
uint len = a_str.length();
uint c = 0;
while (c < len)
{
switch (a_str[c])
{
case '\'':
++c;
while (c < len)
{
switch (a_str[c])
{
case '\\':
result += a_str[c++];
result += a_str[c++];
break;
default:
result += a_str[c++];
break;
}
if (a_str[c] == '\'')
break;
}
break;
default:
break;
}
++c;
}
result += "\"";
}
--- End code ---
killerbot:
what will be the name of the function in GDB ??
parse_wxstring ?
ParseWXString ?
GDB_ParseWXString ?
Unclear beacuse of the type, print function ..
mandrav:
--- Quote from: killerbot on January 24, 2006, 11:03:28 am ---what will be the name of the function in GDB ??
parse_wxstring ?
ParseWXString ?
GDB_ParseWXString ?
Unclear beacuse of the type, print function ..
--- End quote ---
GDB_ParseWXString is the script's function that does the parsing (arbitrarily chosen - unique of course).
When registering the type, wxString in this case, the debugger prepends "print_" to it and converts it to lowercase so the final gdb function will be 'print_wxstring'. You don't need this info, unless you want to call it yourself by using "Debug->Send command".
Urxae:
--- Quote from: mandrav on January 24, 2006, 10:33:24 am ---Implemented it in GDB :lol:
I will have to study CDB a little more before I can implement it there too...
I have not committed it yet because I was in the middle of some other debugger changes. I will finish them all and then commit.
Here's the script that adds wxString support in GDB:
**snip**
--- End quote ---
Some points:
* It looks like it gives a query to run and defines a function to parse the output. Would it not be simpler (and possibly more powerful) if the script could ask the debugger driver to run certain queries? That way you can run multiple queries and the script logic can even dynamically adjust which ones and/or how many times. It also allows for more abstraction from the actual queries, which might allow the same scripts to be used by both GDB and CDB.
* Is the output only allowed to be a string? What if one wanted to define a script for a container type (such as std::vector or std::list instantiations) and have them be expandable to an enumerated list of the content of the container?
I'm thinking of something like this:
+ myvec : std::vector<std::string>
+-[0] "This"
+-[1] "is"
+-[2] "a"
+-[3] "test"
in the watches area (collapsable to just the first line, of course.
* Is there any way these scripts can call each other or otherwise make use of each other? A vector script may want to the elements according to their own type's script, for instance.
* Does this mechanism allow you to watch multiple instantiations of the same template with only one script? (The regex looks promising)
For example: Would it be possible to write a script that parses std::vector<int>, std::vector<std::string> as well as std::vector<wxString>?
Combining some of the above suggestions, maybe the scripts should create a list as output, with elements like (Name, <Watch expression (or string)>). For instance the vector example would output something like
--- Code: ---(("[0]", <string at address0>), ("[1]", <string at address1>), ("[2]", <string at address2>), ("[3]", <string at address3>))
--- End code ---
(in a data structure, not a string) and then the debugger driver or whatever calls the scripts can use the script for std::string to produce the representation of each individual string.
Preferably this would of course be done without the script needing to know what a std::string even is.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version