mirror of
https://github.com/epasveer/seer.git
synced 2026-08-29 08:34:42 +08:00
Cosmetic changes for specifying conditions in breakpoints.
Add the 'if' word to the dialogs. Parse the breakpoints table more effieciently.
This commit is contained in:
@@ -161,7 +161,7 @@
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="conditionalCheckBox">
|
||||
<property name="text">
|
||||
<string>Conditional</string>
|
||||
<string>Condition if:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -106,32 +106,44 @@ void SeerBreakpointsBrowserWidget::handleText (const QString& text) {
|
||||
// }
|
||||
//
|
||||
|
||||
//qDebug().noquote() << bkpt_list;
|
||||
|
||||
QString newtext = Seer::filterEscapes(text); // Filter escaped characters.
|
||||
|
||||
QString body_text = Seer::parseFirst(newtext, "body=", '[', ']', false);
|
||||
|
||||
//qDebug() << body_text;
|
||||
QString body_text = Seer::parseFirst(text, "body=", '[', ']', false);
|
||||
|
||||
if (body_text != "") {
|
||||
|
||||
QStringList bkpt_list = Seer::parse(newtext, "bkpt=", '{', '}', false);
|
||||
|
||||
for ( const auto& bkpt_text : bkpt_list ) {
|
||||
QString number_text = Seer::parseFirst(bkpt_text, "number=", '"', '"', false);
|
||||
QString type_text = Seer::parseFirst(bkpt_text, "type=", '"', '"', false);
|
||||
QString disp_text = Seer::parseFirst(bkpt_text, "disp=", '"', '"', false);
|
||||
QString enabled_text = Seer::parseFirst(bkpt_text, "enabled=", '"', '"', false);
|
||||
QString addr_text = Seer::parseFirst(bkpt_text, "addr=", '"', '"', false);
|
||||
QString func_text = Seer::parseFirst(bkpt_text, "func=", '"', '"', false);
|
||||
QString file_text = Seer::parseFirst(bkpt_text, "file=", '"', '"', false);
|
||||
QString fullname_text = Seer::parseFirst(bkpt_text, "fullname=", '"', '"', false);
|
||||
QString line_text = Seer::parseFirst(bkpt_text, "line=", '"', '"', false);
|
||||
QString thread_groups_text = Seer::parseFirst(bkpt_text, "thread-groups=", '[', ']', false);
|
||||
QString cond_text = Seer::parseFirst(bkpt_text, "cond=", '"', '"', false);
|
||||
QString times_text = Seer::parseFirst(bkpt_text, "times=", '"', '"', false);
|
||||
QString ignore_text = Seer::parseFirst(bkpt_text, "ignore=", '"', '"', false);
|
||||
QString script_text = Seer::parseFirst(bkpt_text, "script=", '{', '}', false);
|
||||
QString original_location_text = Seer::parseFirst(bkpt_text, "original-location=", '"', '"', false);
|
||||
|
||||
//
|
||||
// A different way (better?) of parsing the table output
|
||||
//
|
||||
// Divide test into a list, delimited by a ','.
|
||||
// Then morph that list into a map, delimited by a '='.
|
||||
// Remove bookends.
|
||||
//
|
||||
QStringList items = Seer::parseCommaList(bkpt_text);
|
||||
|
||||
QMap<QString,QString> keyValueMap = Seer::createKeyValueMap(items, '=');
|
||||
|
||||
QString number_text = Seer::filterBookends(keyValueMap["number"], '"', '"');
|
||||
QString type_text = Seer::filterBookends(keyValueMap["type"], '"', '"');
|
||||
QString disp_text = Seer::filterBookends(keyValueMap["disp"], '"', '"');
|
||||
QString enabled_text = Seer::filterBookends(keyValueMap["enabled"], '"', '"');
|
||||
QString addr_text = Seer::filterBookends(keyValueMap["addr"], '"', '"');
|
||||
QString func_text = Seer::filterBookends(keyValueMap["func"], '"', '"');
|
||||
QString file_text = Seer::filterBookends(keyValueMap["file"], '"', '"');
|
||||
QString fullname_text = Seer::filterBookends(keyValueMap["fullname"], '"', '"');
|
||||
QString line_text = Seer::filterBookends(keyValueMap["line"], '"', '"');
|
||||
QString thread_groups_text = Seer::filterBookends(keyValueMap["thread-groups"], '[', ']');
|
||||
QString cond_text = Seer::filterBookends(keyValueMap["cond"], '"', '"');
|
||||
QString times_text = Seer::filterBookends(keyValueMap["times"], '"', '"');
|
||||
QString ignore_text = Seer::filterBookends(keyValueMap["ignore"], '"', '"');
|
||||
QString script_text = Seer::filterBookends(keyValueMap["script"], '{', '}');
|
||||
QString original_location_text = Seer::filterBookends(keyValueMap["original-location"], '"', '"');
|
||||
|
||||
// Only look for 'breakpoint' type break points.
|
||||
if (type_text != "breakpoint") {
|
||||
@@ -334,7 +346,7 @@ void SeerBreakpointsBrowserWidget::handleConditionToolButton () {
|
||||
|
||||
// Get the condition text.
|
||||
bool ok;
|
||||
QString condition = QInputDialog::getText(this, "Seer", "Enter the condition for this breakpoint.\nA blank condition will remove an existing one.", QLineEdit::Normal, items.front()->text(10), &ok);
|
||||
QString condition = QInputDialog::getText(this, "Seer", "Enter the condition for this breakpoint.\nA blank condition will remove an existing one.\n\nif:", QLineEdit::Normal, items.front()->text(10), &ok);
|
||||
|
||||
if (ok == false) {
|
||||
return;
|
||||
|
||||
+109
@@ -297,6 +297,102 @@ namespace Seer {
|
||||
return list;
|
||||
}
|
||||
|
||||
QStringList parseCommaList (const QString& str) {
|
||||
|
||||
//
|
||||
// number="2",type="breakpoint",disp="keep",enabled="y",addr="0x00000000004016cd",func="main(int, char**)",file="hellofibonacci.cpp",fullname="/nas/erniep/Development/seer/tests/hellofibonacci/hellofibonacci.cpp",line="34",thread-groups=["i1"],cond="$_streq(s.c_str(), "21")",times="0",original-location="hellofibonacci.cpp:34"
|
||||
//
|
||||
// returns...
|
||||
//
|
||||
// number="2"
|
||||
// type="breakpoint"
|
||||
// disp="keep"
|
||||
// enabled="y"
|
||||
// addr="0x00000000004016cd"
|
||||
// func="main(int char**)"
|
||||
// file="hellofibonacci.cpp"
|
||||
// fullname="/nas/erniep/Development/seer/tests/hellofibonacci/hellofibonacci.cpp"
|
||||
// line="34"
|
||||
// thread-groups=["i1"]
|
||||
// cond="$_streq(s.c_str() "21")"
|
||||
// times="0"
|
||||
// original-location="hellofibonacci.cpp:34"
|
||||
//
|
||||
|
||||
QStringList list;
|
||||
int index = 0;
|
||||
int state = 0;
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
bool inquotes = false;
|
||||
int bracketlevel = 0;
|
||||
|
||||
while (index < str.length()) {
|
||||
|
||||
// Handle start of field.
|
||||
if (state == 0) { // Start of field.
|
||||
start = index;
|
||||
end = index;
|
||||
state = 1; // Look for end of field (a command or eol).
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle end of field.
|
||||
if (state == 1) {
|
||||
|
||||
// Handle """
|
||||
if (str[index] == '"') {
|
||||
if (inquotes == false) {
|
||||
inquotes = true;
|
||||
}else{
|
||||
inquotes = false;
|
||||
}
|
||||
|
||||
index++; continue;
|
||||
}
|
||||
|
||||
// Handle ","
|
||||
if (str[index] == ',') {
|
||||
if (inquotes) {
|
||||
index++; continue;
|
||||
}
|
||||
|
||||
// Extract field, only if the bracket level is at zero.
|
||||
// Otherwise, continue.
|
||||
if (bracketlevel == 0) {
|
||||
end = index;
|
||||
|
||||
QString field = str.mid(start, end-start);
|
||||
|
||||
list.append(field.trimmed());
|
||||
|
||||
state = 0; // Look for the next field.
|
||||
}
|
||||
|
||||
index++; continue;
|
||||
}
|
||||
|
||||
// Handle any other character.
|
||||
index++; continue;
|
||||
}
|
||||
|
||||
qDebug() << "Bad state!";
|
||||
index++; continue;
|
||||
}
|
||||
|
||||
// Handle last field, if any.
|
||||
if (state == 1) {
|
||||
end = index;
|
||||
|
||||
QString field = str.mid(start, end-start);
|
||||
|
||||
list.append(field.trimmed());
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QStringList parseCommaList (const QString& str, QChar startBracket, QChar endBracket) {
|
||||
|
||||
// name = "Pasveer, Ernie", age = 60, salary = 0.25, location = {city = "Houston", state = "Texas", zip = 77063}
|
||||
@@ -402,6 +498,19 @@ namespace Seer {
|
||||
return list;
|
||||
}
|
||||
|
||||
QMap<QString,QString> createKeyValueMap (const QStringList& list, QChar separator) {
|
||||
|
||||
QMap<QString,QString> map;
|
||||
|
||||
for (const auto& i : list) {
|
||||
QStringPair pair = parseNameValue(i, separator);
|
||||
|
||||
map[pair.first] = pair.second;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "QStringPair.h"
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QMap>
|
||||
|
||||
namespace Seer {
|
||||
|
||||
@@ -17,7 +18,9 @@ namespace Seer {
|
||||
bool hasBookends (const QString& str, QChar startBracket, QChar endBracket);
|
||||
QString filterBookends (const QString& str, QChar startBracket, QChar endBracket);
|
||||
QStringList filterBookends (const QStringList& strings, QChar startBracket, QChar endBracket);
|
||||
QStringList parseCommaList (const QString& str);
|
||||
QStringList parseCommaList (const QString& str, QChar startBracket, QChar endBracket);
|
||||
QMap<QString,QString> createKeyValueMap (const QStringList& list, QChar separator);
|
||||
QStringPair parseNameValue (const QString& str, QChar separator);
|
||||
QString quoteChars (const QString& str, const QString& chars);
|
||||
QStringList quoteChars (const QStringList& strings, const QString& chars);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
gdbmi_condition
|
||||
core*
|
||||
@@ -0,0 +1,10 @@
|
||||
.PHONY: all
|
||||
all: gdbmi_condition
|
||||
|
||||
gdbmi_condition: gdbmi_condition.cpp
|
||||
g++ -g -o gdbmi_condition gdbmi_condition.cpp
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f gdbmi_condition gdbmi_condition.o
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
|
||||
std::string name = "";
|
||||
|
||||
name = "ernie";
|
||||
|
||||
// Create the breakpoint with a string condition.
|
||||
//
|
||||
// -break-insert -c 'name.c_str() == "ernie"' gdbmi_condition.cpp:16 // Failed parsing.
|
||||
// -break-insert -c '$_streq(name.c_str(), "ernie")' gdbmi_condition.cpp:16 // Failed parsing.
|
||||
// -break-insert -c 'strcmp("xxxxx", name.c_str() == 0' gdbmi_condition.cpp:16 // Is accepted but breaks eventhough strings are different.
|
||||
|
||||
std::cout << "Name is: " << name << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
break -source /nas/erniep/Development/seer/tests/hellofibonacci/hellofibonacci.cpp -line 23
|
||||
break -source /nas/erniep/Development/seer/tests/hellofibonacci/hellofibonacci.cpp -line 29
|
||||
condition $bpnum nextTerm > 10
|
||||
break hellofibonacci.cpp:34
|
||||
condition $bpnum $_streq(s.c_str(), "21")
|
||||
|
||||
@@ -26,7 +26,12 @@ int main (int argc, char* argv[]) {
|
||||
nextTerm = t1 + t2;
|
||||
|
||||
while (nextTerm <= n) {
|
||||
std::cout << nextTerm << ", ";
|
||||
|
||||
std::string s = "";
|
||||
|
||||
s = std::to_string(nextTerm);
|
||||
|
||||
std::cout << s << ", ";
|
||||
t1 = t2;
|
||||
t2 = nextTerm;
|
||||
nextTerm = t1 + t2;
|
||||
|
||||
Reference in New Issue
Block a user