implemented: watch var handles
This commit is contained in:
parent
39ab388458
commit
92fcd9b923
4
NEWS.md
4
NEWS.md
|
@ -1,3 +1,7 @@
|
||||||
|
Version 0.10.0 For Dev-C++ 7 Beta
|
||||||
|
- enhancement: use gdb/mi interface to communicate with gdb debug session
|
||||||
|
- enhancement: better display of watch vars
|
||||||
|
|
||||||
Version 0.9.3 For Dev-C++ 7 Beta
|
Version 0.9.3 For Dev-C++ 7 Beta
|
||||||
- fix: the count in the title of issues view isn't correct
|
- fix: the count in the title of issues view isn't correct
|
||||||
- fix: columns calculation not correct when paint lines containing chinese characters
|
- fix: columns calculation not correct when paint lines containing chinese characters
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -27,6 +27,9 @@ Debugger::Debugger(QObject *parent) : QObject(parent)
|
||||||
mReader = nullptr;
|
mReader = nullptr;
|
||||||
mCommandChanged = false;
|
mCommandChanged = false;
|
||||||
mLeftPageIndexBackup = -1;
|
mLeftPageIndexBackup = -1;
|
||||||
|
|
||||||
|
connect(mWatchModel, &WatchModel::fetchChildren,
|
||||||
|
this, &Debugger::fetchVarChildren);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Debugger::start()
|
bool Debugger::start()
|
||||||
|
@ -58,6 +61,7 @@ bool Debugger::start()
|
||||||
tr("Can''t find debugger in : \"%1\"").arg(debuggerPath));
|
tr("Can''t find debugger in : \"%1\"").arg(debuggerPath));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
mWatchModel->resetAllVarInfos();
|
||||||
mReader = new DebugReader(this);
|
mReader = new DebugReader(this);
|
||||||
mReader->setDebuggerPath(debuggerPath);
|
mReader->setDebuggerPath(debuggerPath);
|
||||||
connect(mReader, &QThread::finished,this,&Debugger::clearUpReader);
|
connect(mReader, &QThread::finished,this,&Debugger::clearUpReader);
|
||||||
|
@ -81,10 +85,20 @@ bool Debugger::start()
|
||||||
&Debugger::updateRegisterNames);
|
&Debugger::updateRegisterNames);
|
||||||
connect(mReader, &DebugReader::registerValuesUpdated, this,
|
connect(mReader, &DebugReader::registerValuesUpdated, this,
|
||||||
&Debugger::updateRegisterValues);
|
&Debugger::updateRegisterValues);
|
||||||
|
connect(mReader, &DebugReader::varCreated,mWatchModel,
|
||||||
|
&WatchModel::updateVarInfo);
|
||||||
|
connect(mReader, &DebugReader::prepareVarChildren,mWatchModel,
|
||||||
|
&WatchModel::prepareVarChildren);
|
||||||
|
connect(mReader, &DebugReader::addVarChild,mWatchModel,
|
||||||
|
&WatchModel::addVarChild);
|
||||||
|
connect(mReader, &DebugReader::varValueUpdated,mWatchModel,
|
||||||
|
&WatchModel::updateVarValue);
|
||||||
connect(mReader, &DebugReader::inferiorContinued,pMainWindow,
|
connect(mReader, &DebugReader::inferiorContinued,pMainWindow,
|
||||||
&MainWindow::removeActiveBreakpoints);
|
&MainWindow::removeActiveBreakpoints);
|
||||||
connect(mReader, &DebugReader::inferiorStopped,pMainWindow,
|
connect(mReader, &DebugReader::inferiorStopped,pMainWindow,
|
||||||
&MainWindow::setActiveBreakpoint);
|
&MainWindow::setActiveBreakpoint);
|
||||||
|
connect(mReader, &DebugReader::inferiorStopped,this,
|
||||||
|
&Debugger::refreshWatchVars);
|
||||||
|
|
||||||
mReader->registerInferiorStoppedCommand("-stack-list-frames","");
|
mReader->registerInferiorStoppedCommand("-stack-list-frames","");
|
||||||
mReader->registerInferiorStoppedCommand("-stack-list-variables", "--all-values");
|
mReader->registerInferiorStoppedCommand("-stack-list-variables", "--all-values");
|
||||||
|
@ -110,10 +124,6 @@ void Debugger::clearUpReader()
|
||||||
mReader->deleteLater();
|
mReader->deleteLater();
|
||||||
mReader=nullptr;
|
mReader=nullptr;
|
||||||
|
|
||||||
// if WatchVarList.Count = 0 then // nothing worth showing, restore view
|
|
||||||
// MainForm.LeftPageControl.ActivePageIndex := LeftPageIndexBackup;
|
|
||||||
|
|
||||||
// // Close CPU window
|
|
||||||
if (pMainWindow->cpuDialog()!=nullptr) {
|
if (pMainWindow->cpuDialog()!=nullptr) {
|
||||||
pMainWindow->cpuDialog()->close();
|
pMainWindow->cpuDialog()->close();
|
||||||
}
|
}
|
||||||
|
@ -129,9 +139,9 @@ void Debugger::clearUpReader()
|
||||||
|
|
||||||
mBacktraceModel->clear();
|
mBacktraceModel->clear();
|
||||||
|
|
||||||
for(PWatchVar var:mWatchModel->watchVars()) {
|
mWatchModel->clearAllVarInfos();
|
||||||
invalidateWatchVar(var);
|
|
||||||
}
|
mBreakpointModel->invalidateAllBreakpointNumbers();
|
||||||
|
|
||||||
pMainWindow->updateEditorActions();
|
pMainWindow->updateEditorActions();
|
||||||
}
|
}
|
||||||
|
@ -279,37 +289,43 @@ void Debugger::sendAllBreakpointsToDebugger()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::addWatchVar(const QString &namein)
|
void Debugger::addWatchVar(const QString &expression)
|
||||||
{
|
{
|
||||||
// Don't allow duplicates...
|
// Don't allow duplicates...
|
||||||
PWatchVar oldVar = mWatchModel->findWatchVar(namein);
|
PWatchVar oldVar = mWatchModel->findWatchVar(expression);
|
||||||
if (oldVar)
|
if (oldVar)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PWatchVar var = std::make_shared<WatchVar>();
|
PWatchVar var = std::make_shared<WatchVar>();
|
||||||
var->parent= nullptr;
|
var->parent= nullptr;
|
||||||
var->expression = namein;
|
var->expression = expression;
|
||||||
var->value = tr("Execute to evaluate");
|
var->value = tr("Execute to evaluate");
|
||||||
var->numChild = 0;
|
var->numChild = 0;
|
||||||
var->hasMore = false;
|
var->hasMore = false;
|
||||||
|
var->parent = nullptr;
|
||||||
|
|
||||||
mWatchModel->addWatchVar(var);
|
mWatchModel->addWatchVar(var);
|
||||||
sendWatchCommand(var);
|
sendWatchCommand(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::renameWatchVar(const QString &oldname, const QString &newname)
|
void Debugger::modifyWatchVarExpression(const QString &oldExpr, const QString &newExpr)
|
||||||
{
|
{
|
||||||
// check if name already exists;
|
// check if name already exists;
|
||||||
PWatchVar var = mWatchModel->findWatchVar(newname);
|
PWatchVar var = mWatchModel->findWatchVar(newExpr);
|
||||||
if (var)
|
if (var)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var = mWatchModel->findWatchVar(oldname);
|
var = mWatchModel->findWatchVar(oldExpr);
|
||||||
if (var) {
|
if (var) {
|
||||||
var->name = newname;
|
if (mExecuting && !var->expression.isEmpty())
|
||||||
if (mExecuting && var->gdbIndex!=-1)
|
|
||||||
sendRemoveWatchCommand(var);
|
sendRemoveWatchCommand(var);
|
||||||
invalidateWatchVar(var);
|
var->expression = newExpr;
|
||||||
|
var->type.clear();
|
||||||
|
var->value.clear();
|
||||||
|
var->hasMore = false;
|
||||||
|
var->numChild=0;
|
||||||
|
var->name.clear();
|
||||||
|
var->children.clear();
|
||||||
|
|
||||||
if (mExecuting) {
|
if (mExecuting) {
|
||||||
sendWatchCommand(var);
|
sendWatchCommand(var);
|
||||||
|
@ -319,9 +335,16 @@ void Debugger::renameWatchVar(const QString &oldname, const QString &newname)
|
||||||
|
|
||||||
void Debugger::refreshWatchVars()
|
void Debugger::refreshWatchVars()
|
||||||
{
|
{
|
||||||
for (PWatchVar var:mWatchModel->watchVars()) {
|
if (mExecuting) {
|
||||||
if (var->gdbIndex == -1)
|
sendAllWatchVarsToDebugger();
|
||||||
sendWatchCommand(var);
|
sendCommand("-var-update"," --all-values *");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugger::fetchVarChildren(const QString &varName)
|
||||||
|
{
|
||||||
|
if (mExecuting) {
|
||||||
|
sendCommand("-var-list-children",varName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,75 +355,37 @@ void Debugger::removeWatchVars(bool deleteparent)
|
||||||
} else {
|
} else {
|
||||||
for(const PWatchVar& var:mWatchModel->watchVars()) {
|
for(const PWatchVar& var:mWatchModel->watchVars()) {
|
||||||
sendRemoveWatchCommand(var);
|
sendRemoveWatchCommand(var);
|
||||||
invalidateWatchVar(var);
|
|
||||||
}
|
}
|
||||||
|
mWatchModel->clearAllVarInfos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::removeWatchVar(const QModelIndex &index)
|
void Debugger::removeWatchVar(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
|
PWatchVar var = mWatchModel->findWatchVar(index);
|
||||||
|
if (!var)
|
||||||
|
return;
|
||||||
|
sendRemoveWatchCommand(var);
|
||||||
mWatchModel->removeWatchVar(index);
|
mWatchModel->removeWatchVar(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::invalidateAllVars()
|
void Debugger::sendAllWatchVarsToDebugger()
|
||||||
{
|
|
||||||
mReader->setInvalidateAllVars(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Debugger::sendAllWatchvarsToDebugger()
|
|
||||||
{
|
{
|
||||||
for (PWatchVar var:mWatchModel->watchVars()) {
|
for (PWatchVar var:mWatchModel->watchVars()) {
|
||||||
|
if (var->name.isEmpty())
|
||||||
sendWatchCommand(var);
|
sendWatchCommand(var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::invalidateWatchVar(const QString &name)
|
PWatchVar Debugger::findWatchVar(const QString &expression)
|
||||||
{
|
{
|
||||||
PWatchVar var = mWatchModel->findWatchVar(name);
|
return mWatchModel->findWatchVar(expression);
|
||||||
if (var) {
|
|
||||||
invalidateWatchVar(var);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Debugger::invalidateWatchVar(PWatchVar var)
|
|
||||||
{
|
|
||||||
var->gdbIndex = -1;
|
|
||||||
QString value;
|
|
||||||
if (mExecuting) {
|
|
||||||
value = tr("Not found in current context");
|
|
||||||
} else {
|
|
||||||
value = tr("Execute to evaluate");
|
|
||||||
}
|
|
||||||
var->value = value;
|
|
||||||
if (var->children.isEmpty()) {
|
|
||||||
mWatchModel->notifyUpdated(var);
|
|
||||||
} else {
|
|
||||||
mWatchModel->beginUpdate();
|
|
||||||
var->children.clear();
|
|
||||||
mWatchModel->endUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PWatchVar Debugger::findWatchVar(const QString &name)
|
|
||||||
{
|
|
||||||
return mWatchModel->findWatchVar(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//void Debugger::notifyWatchVarUpdated(PWatchVar var)
|
//void Debugger::notifyWatchVarUpdated(PWatchVar var)
|
||||||
//{
|
//{
|
||||||
// mWatchModel->notifyUpdated(var);
|
// mWatchModel->notifyUpdated(var);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void Debugger::notifyBeforeProcessWatchVar()
|
|
||||||
{
|
|
||||||
mWatchModel->beginUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Debugger::notifyAfterProcessWatchVar()
|
|
||||||
{
|
|
||||||
mWatchModel->endUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
BacktraceModel* Debugger::backtraceModel()
|
BacktraceModel* Debugger::backtraceModel()
|
||||||
{
|
{
|
||||||
return mBacktraceModel;
|
return mBacktraceModel;
|
||||||
|
@ -413,7 +398,7 @@ BreakpointModel *Debugger::breakpointModel()
|
||||||
|
|
||||||
void Debugger::sendWatchCommand(PWatchVar var)
|
void Debugger::sendWatchCommand(PWatchVar var)
|
||||||
{
|
{
|
||||||
sendCommand("-var-carete", QString(" - %1").arg(var->expression));
|
sendCommand("-var-create", var->expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::sendRemoveWatchCommand(PWatchVar var)
|
void Debugger::sendRemoveWatchCommand(PWatchVar var)
|
||||||
|
@ -587,7 +572,6 @@ DebugReader::DebugReader(Debugger* debugger, QObject *parent) : QThread(parent),
|
||||||
mDebugger = debugger;
|
mDebugger = debugger;
|
||||||
mProcess = nullptr;
|
mProcess = nullptr;
|
||||||
mCmdRunning = false;
|
mCmdRunning = false;
|
||||||
mInvalidateAllVars = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugReader::postCommand(const QString &Command, const QString &Params,
|
void DebugReader::postCommand(const QString &Command, const QString &Params,
|
||||||
|
@ -740,6 +724,15 @@ void DebugReader::processResult(const QByteArray &result)
|
||||||
case GDBMIResultType::RegisterValues:
|
case GDBMIResultType::RegisterValues:
|
||||||
handleRegisterValue(multiValues["register-values"].array());
|
handleRegisterValue(multiValues["register-values"].array());
|
||||||
return;
|
return;
|
||||||
|
case GDBMIResultType::CreateVar:
|
||||||
|
handleCreateVar(multiValues);
|
||||||
|
return;
|
||||||
|
case GDBMIResultType::ListVarChildren:
|
||||||
|
handleListVarChildren(multiValues);
|
||||||
|
return;
|
||||||
|
case GDBMIResultType::UpdateVarValue:
|
||||||
|
handleUpdateVarValue(multiValues["changelist"].array());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -846,12 +839,6 @@ void DebugReader::processDebugOutput(const QByteArray& debugOutput)
|
||||||
// Only update once per update at most
|
// Only update once per update at most
|
||||||
//WatchView.Items.BeginUpdate;
|
//WatchView.Items.BeginUpdate;
|
||||||
|
|
||||||
if (mInvalidateAllVars) {
|
|
||||||
//invalidate all vars when there's first output
|
|
||||||
mDebugger->removeWatchVars(false);
|
|
||||||
mInvalidateAllVars = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit parseStarted();
|
emit parseStarted();
|
||||||
|
|
||||||
mConsoleOutput.clear();
|
mConsoleOutput.clear();
|
||||||
|
@ -899,190 +886,6 @@ void DebugReader::runInferiorStoppedHook()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DebugReader::processEvalOutput()
|
|
||||||
{
|
|
||||||
int indent = 0;
|
|
||||||
|
|
||||||
// First line gets special treatment
|
|
||||||
QString result ="";
|
|
||||||
if (result.startsWith('{'))
|
|
||||||
indent+=4;
|
|
||||||
|
|
||||||
// Collect all data, add formatting in between
|
|
||||||
// AnnotationType nextAnnotation;
|
|
||||||
// QString nextLine;
|
|
||||||
// bool shouldExit = false;
|
|
||||||
// do {
|
|
||||||
// nextAnnotation = getNextAnnotation();
|
|
||||||
// nextLine = getNextLine();
|
|
||||||
// switch(nextAnnotation) {
|
|
||||||
// // Change indent if { or } is found
|
|
||||||
// case AnnotationType::TFieldBegin:
|
|
||||||
// result += "\r\n" + QString(4,' ');
|
|
||||||
// break;
|
|
||||||
// case AnnotationType::TFieldValue:
|
|
||||||
// if (nextLine.startsWith('{') && (peekNextAnnotation() !=
|
|
||||||
// AnnotationType::TArrayBegin))
|
|
||||||
// indent+=4;
|
|
||||||
// break;
|
|
||||||
// case AnnotationType::TFieldEnd:
|
|
||||||
// if (nextLine.endsWith('}')) {
|
|
||||||
// indent-=4;
|
|
||||||
// result += "\r\n" + QString(4,' ');
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// case AnnotationType::TEOF:
|
|
||||||
// case AnnotationType::TValueHistoryEnd:
|
|
||||||
// case AnnotationType::TDisplayEnd:
|
|
||||||
// shouldExit = true;
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// result += nextLine;
|
|
||||||
// } while (!shouldExit);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::processWatchOutput(PWatchVar watchVar)
|
|
||||||
{
|
|
||||||
// // Expand if it was expanded or if it didn't have any children
|
|
||||||
// bool ParentWasExpanded = false;
|
|
||||||
|
|
||||||
// Do not remove root node of watch variable
|
|
||||||
|
|
||||||
watchVar->children.clear();
|
|
||||||
watchVar->value = "";
|
|
||||||
// Process output parsed by ProcessEvalStruct
|
|
||||||
QString s = processEvalOutput();
|
|
||||||
|
|
||||||
QStringList tokens = tokenize(s);
|
|
||||||
PWatchVar parentVar = watchVar;
|
|
||||||
PWatchVar currentVar = watchVar;
|
|
||||||
|
|
||||||
QVector<PWatchVar> varStack;
|
|
||||||
int i=0;
|
|
||||||
while (i<tokens.length()) {
|
|
||||||
QString token = tokens[i];
|
|
||||||
QChar ch = token[0];
|
|
||||||
if (ch =='_' || (ch>='a' && ch<='z')
|
|
||||||
|| (ch>='A' && ch<='Z') || (ch>127)) {
|
|
||||||
//is identifier,create new child node
|
|
||||||
PWatchVar newVar = std::make_shared<WatchVar>();
|
|
||||||
newVar->parent = parentVar.get();
|
|
||||||
newVar->name = token;
|
|
||||||
newVar->fullName = parentVar->fullName + '.'+token;
|
|
||||||
newVar->value = "";
|
|
||||||
newVar->gdbIndex = -1;
|
|
||||||
parentVar->children.append(newVar);
|
|
||||||
currentVar = newVar;
|
|
||||||
} else if (ch == '{') {
|
|
||||||
if (parentVar->value.isEmpty()) {
|
|
||||||
parentVar->value = "{";
|
|
||||||
} else {
|
|
||||||
PWatchVar newVar = std::make_shared<WatchVar>();
|
|
||||||
newVar->parent = parentVar.get();
|
|
||||||
if (parentVar) {
|
|
||||||
int count = parentVar->children.count();
|
|
||||||
newVar->name = QString("[%1]").arg(count);
|
|
||||||
newVar->fullName = parentVar->fullName + newVar->name;
|
|
||||||
} else {
|
|
||||||
newVar->name = QString("[0]");
|
|
||||||
newVar->fullName = newVar->name;
|
|
||||||
}
|
|
||||||
newVar->value = "{";
|
|
||||||
parentVar->children.append(newVar);
|
|
||||||
varStack.push_back(parentVar);
|
|
||||||
parentVar = newVar;
|
|
||||||
}
|
|
||||||
currentVar = nullptr;
|
|
||||||
} else if (ch == '}') {
|
|
||||||
currentVar = nullptr;
|
|
||||||
PWatchVar newVar = std::make_shared<WatchVar>();
|
|
||||||
newVar->parent = parentVar.get();
|
|
||||||
newVar->name = "";
|
|
||||||
newVar->value = "}";
|
|
||||||
newVar->gdbIndex = -1;
|
|
||||||
parentVar->children.append(newVar);
|
|
||||||
if (!varStack.isEmpty()) {
|
|
||||||
parentVar = varStack.back();
|
|
||||||
varStack.pop_back();
|
|
||||||
}
|
|
||||||
} else if (ch == '=') {
|
|
||||||
// just skip it
|
|
||||||
} else if (ch == ',') {
|
|
||||||
currentVar = nullptr;
|
|
||||||
} else {
|
|
||||||
if (currentVar) {
|
|
||||||
if (currentVar->value.isEmpty()) {
|
|
||||||
currentVar->value = token;
|
|
||||||
} else {
|
|
||||||
currentVar->value += " "+token;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PWatchVar newVar = std::make_shared<WatchVar>();
|
|
||||||
newVar->parent = parentVar.get();
|
|
||||||
newVar->name = QString("[%1]")
|
|
||||||
.arg(parentVar->children.count());
|
|
||||||
newVar->fullName = parentVar->fullName + newVar->name;
|
|
||||||
newVar->value = token;
|
|
||||||
newVar->gdbIndex = -1;
|
|
||||||
parentVar->children.append(newVar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
// add placeholder name for variable name so we can format structs using one rule
|
|
||||||
|
|
||||||
// Add children based on indent
|
|
||||||
// QStringList lines = TextToLines(s);
|
|
||||||
|
|
||||||
// for (const QString& line:lines) {
|
|
||||||
// // Format node text. Remove trailing comma
|
|
||||||
// QString nodeText = line.trimmed();
|
|
||||||
// if (nodeText.endsWith(',')) {
|
|
||||||
// nodeText.remove(nodeText.length()-1,1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (nodeText.endsWith('{')) { // new member struct
|
|
||||||
// if (parentVar->text.isEmpty()) { // root node, replace text only
|
|
||||||
// parentVar->text = nodeText;
|
|
||||||
// } else {
|
|
||||||
// PWatchVar newVar = std::make_shared<WatchVar>();
|
|
||||||
// newVar->parent = parentVar.get();
|
|
||||||
// newVar->name = "";
|
|
||||||
// newVar->text = nodeText;
|
|
||||||
// newVar->gdbIndex = -1;
|
|
||||||
// parentVar->children.append(newVar);
|
|
||||||
// varStack.push_back(parentVar);
|
|
||||||
// parentVar = newVar;
|
|
||||||
// }
|
|
||||||
// } else if (nodeText.startsWith('}')) { // end of struct, change parent
|
|
||||||
// PWatchVar newVar = std::make_shared<WatchVar>();
|
|
||||||
// newVar->parent = parentVar.get();
|
|
||||||
// newVar->name = "";
|
|
||||||
// newVar->text = "}";
|
|
||||||
// newVar->gdbIndex = -1;
|
|
||||||
// parentVar->children.append(newVar);
|
|
||||||
// if (!varStack.isEmpty()) {
|
|
||||||
// parentVar = varStack.back();
|
|
||||||
// varStack.pop_back();
|
|
||||||
// }
|
|
||||||
// } else { // next parent member/child
|
|
||||||
// if (parentVar->text.isEmpty()) { // root node, replace text only
|
|
||||||
// parentVar->text = nodeText;
|
|
||||||
// } else {
|
|
||||||
// PWatchVar newVar = std::make_shared<WatchVar>();
|
|
||||||
// newVar->parent = parentVar.get();
|
|
||||||
// newVar->name = "";
|
|
||||||
// newVar->text = nodeText;
|
|
||||||
// newVar->gdbIndex = -1;
|
|
||||||
// parentVar->children.append(newVar);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// TODO: remember expansion state
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::runNextCmd()
|
void DebugReader::runNextCmd()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mCmdQueueMutex);
|
QMutexLocker locker(&mCmdQueueMutex);
|
||||||
|
@ -1100,10 +903,19 @@ void DebugReader::runNextCmd()
|
||||||
emit cmdStarted();
|
emit cmdStarted();
|
||||||
|
|
||||||
QByteArray s;
|
QByteArray s;
|
||||||
|
QByteArray params;
|
||||||
s=pCmd->command.toLocal8Bit();
|
s=pCmd->command.toLocal8Bit();
|
||||||
if (!pCmd->params.isEmpty()) {
|
if (!pCmd->params.isEmpty()) {
|
||||||
s+= ' '+pCmd->params.toLocal8Bit();
|
params = pCmd->params.toLocal8Bit();
|
||||||
}
|
}
|
||||||
|
if (pCmd->command == "-var-create") {
|
||||||
|
//hack for variable creation,to easy remember var expression
|
||||||
|
params = " - @ "+params;
|
||||||
|
} else if (pCmd->command == "-var-list-children") {
|
||||||
|
//hack for list variable children,to easy remember var expression
|
||||||
|
params = " --all-values " + params;
|
||||||
|
}
|
||||||
|
s+=" "+params;
|
||||||
s+= "\n";
|
s+= "\n";
|
||||||
if (mProcess->write(s)<0) {
|
if (mProcess->write(s)<0) {
|
||||||
emit writeToDebugFailed();
|
emit writeToDebugFailed();
|
||||||
|
@ -1113,9 +925,9 @@ void DebugReader::runNextCmd()
|
||||||
if (pSettings->debugger().enableDebugConsole() ) {
|
if (pSettings->debugger().enableDebugConsole() ) {
|
||||||
//update debug console
|
//update debug console
|
||||||
if (!pSettings->debugger().showDetailLog()) {
|
if (!pSettings->debugger().showDetailLog()) {
|
||||||
emit changeDebugConsoleLastLine(pCmd->command + ' ' + pCmd->params);
|
emit changeDebugConsoleLastLine(pCmd->command + ' ' + params);
|
||||||
} else {
|
} else {
|
||||||
emit changeDebugConsoleLastLine(pCmd->command + ' ' + pCmd->params);
|
emit changeDebugConsoleLastLine(pCmd->command + ' ' + params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1309,6 +1121,62 @@ void DebugReader::handleRegisterValue(const QList<GDBMIResultParser::ParseValue>
|
||||||
emit registerValuesUpdated(result);
|
emit registerValuesUpdated(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugReader::handleCreateVar(const GDBMIResultParser::ParseObject &multiVars)
|
||||||
|
{
|
||||||
|
if (!mCurrentCmd)
|
||||||
|
return;
|
||||||
|
QString expression = mCurrentCmd->params;
|
||||||
|
QString name = multiVars["name"].value();
|
||||||
|
int numChild = multiVars["numchild"].intValue(0);
|
||||||
|
QString value = multiVars["value"].value();
|
||||||
|
QString type = multiVars["type"].value();
|
||||||
|
bool hasMore = multiVars["has_more"].value() != "0";
|
||||||
|
emit varCreated(expression,name,numChild,value,type,hasMore);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugReader::handleListVarChildren(const GDBMIResultParser::ParseObject &multiVars)
|
||||||
|
{
|
||||||
|
if (!mCurrentCmd)
|
||||||
|
return;
|
||||||
|
QString parentName = mCurrentCmd->params;
|
||||||
|
int parentNumChild = multiVars["numchild"].intValue(0);
|
||||||
|
QList<GDBMIResultParser::ParseValue> children = multiVars["children"].array();
|
||||||
|
bool hasMore = multiVars["has_more"].value()!="0";
|
||||||
|
emit prepareVarChildren(parentName,parentNumChild,hasMore);
|
||||||
|
foreach(const GDBMIResultParser::ParseValue& child, children) {
|
||||||
|
GDBMIResultParser::ParseObject childObj = child.object();
|
||||||
|
QString name = childObj["name"].value();
|
||||||
|
QString exp = childObj["exp"].value();
|
||||||
|
int numChild = childObj["numchild"].intValue(0);
|
||||||
|
QString value = childObj["value"].value();
|
||||||
|
QString type = childObj["type"].value();
|
||||||
|
bool hasMore = childObj["has_more"].value() != "0";
|
||||||
|
emit addVarChild(parentName,
|
||||||
|
name,
|
||||||
|
exp,
|
||||||
|
numChild,
|
||||||
|
value,
|
||||||
|
type,
|
||||||
|
hasMore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugReader::handleUpdateVarValue(const QList<GDBMIResultParser::ParseValue> &changes)
|
||||||
|
{
|
||||||
|
foreach (const GDBMIResultParser::ParseValue& value, changes) {
|
||||||
|
GDBMIResultParser::ParseObject obj = value.object();
|
||||||
|
QString name = obj["name"].value();
|
||||||
|
QString val = obj["value"].value();
|
||||||
|
QString inScope = obj["in_scope"].value();
|
||||||
|
bool typeChanged = (obj["type_changed"].value()=="true");
|
||||||
|
QString newType = obj["new_type"].value();
|
||||||
|
int newNumChildren = obj["new_num_children"].intValue(-1);
|
||||||
|
bool hasMore = (obj["has_more"].value() == "1");
|
||||||
|
emit varValueUpdated(name,val,inScope,typeChanged,newType,newNumChildren,
|
||||||
|
hasMore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray DebugReader::removeToken(const QByteArray &line)
|
QByteArray DebugReader::removeToken(const QByteArray &line)
|
||||||
{
|
{
|
||||||
int p=0;
|
int p=0;
|
||||||
|
@ -1374,16 +1242,6 @@ bool DebugReader::processExited() const
|
||||||
return mProcessExited;
|
return mProcessExited;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebugReader::invalidateAllVars() const
|
|
||||||
{
|
|
||||||
return mInvalidateAllVars;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::setInvalidateAllVars(bool invalidateAllVars)
|
|
||||||
{
|
|
||||||
mInvalidateAllVars = invalidateAllVars;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DebugReader::debuggerPath() const
|
QString DebugReader::debuggerPath() const
|
||||||
{
|
{
|
||||||
return mDebuggerPath;
|
return mDebuggerPath;
|
||||||
|
@ -1810,7 +1668,6 @@ QVariant WatchModel::data(const QModelIndex &index, int role) const
|
||||||
WatchVar* item = static_cast<WatchVar*>(index.internalPointer());
|
WatchVar* item = static_cast<WatchVar*>(index.internalPointer());
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
//qDebug()<<"item->text:"<<item->text;
|
|
||||||
switch(index.column()) {
|
switch(index.column()) {
|
||||||
case 0:
|
case 0:
|
||||||
return item->expression;
|
return item->expression;
|
||||||
|
@ -1827,7 +1684,6 @@ QModelIndex WatchModel::index(int row, int column, const QModelIndex &parent) co
|
||||||
{
|
{
|
||||||
if (!hasIndex(row,column,parent))
|
if (!hasIndex(row,column,parent))
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
|
||||||
WatchVar* parentItem;
|
WatchVar* parentItem;
|
||||||
PWatchVar pChild;
|
PWatchVar pChild;
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
|
@ -1897,9 +1753,9 @@ void WatchModel::addWatchVar(PWatchVar watchVar)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->beginInsertRows(QModelIndex(),mWatchVars.size(),mWatchVars.size());
|
beginInsertRows(QModelIndex(),mWatchVars.count(),mWatchVars.count());
|
||||||
mWatchVars.append(watchVar);
|
mWatchVars.append(watchVar);
|
||||||
this->endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchModel::removeWatchVar(const QString &express)
|
void WatchModel::removeWatchVar(const QString &express)
|
||||||
|
@ -1909,6 +1765,8 @@ void WatchModel::removeWatchVar(const QString &express)
|
||||||
if (express == var->expression) {
|
if (express == var->expression) {
|
||||||
this->beginResetModel();
|
this->beginResetModel();
|
||||||
//this->beginRemoveRows(QModelIndex(),i,i);
|
//this->beginRemoveRows(QModelIndex(),i,i);
|
||||||
|
if (mVarIndex.contains(var->name))
|
||||||
|
mVarIndex.remove(var->name);
|
||||||
mWatchVars.removeAt(i);
|
mWatchVars.removeAt(i);
|
||||||
//this->endRemoveRows();
|
//this->endRemoveRows();
|
||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
|
@ -1920,6 +1778,9 @@ void WatchModel::removeWatchVar(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
int r=index.row();
|
int r=index.row();
|
||||||
this->beginRemoveRows(QModelIndex(),r,r);
|
this->beginRemoveRows(QModelIndex(),r,r);
|
||||||
|
PWatchVar var = mWatchVars[r];
|
||||||
|
if (mVarIndex.contains(var->name))
|
||||||
|
mVarIndex.remove(var->name);
|
||||||
mWatchVars.removeAt(r);
|
mWatchVars.removeAt(r);
|
||||||
this->endRemoveRows();
|
this->endRemoveRows();
|
||||||
}
|
}
|
||||||
|
@ -1936,24 +1797,124 @@ const QList<PWatchVar> &WatchModel::watchVars()
|
||||||
return mWatchVars;
|
return mWatchVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
PWatchVar WatchModel::findWatchVar(const QString &name)
|
PWatchVar WatchModel::findWatchVar(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return PWatchVar();
|
||||||
|
int r=index.row();
|
||||||
|
return mWatchVars[r];
|
||||||
|
}
|
||||||
|
|
||||||
|
PWatchVar WatchModel::findWatchVar(const QString &expr)
|
||||||
{
|
{
|
||||||
for (PWatchVar var:mWatchVars) {
|
for (PWatchVar var:mWatchVars) {
|
||||||
if (name == var->name) {
|
if (expr == var->expression) {
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PWatchVar();
|
return PWatchVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
PWatchVar WatchModel::findWatchVar(int gdbIndex)
|
void WatchModel::resetAllVarInfos()
|
||||||
{
|
{
|
||||||
for (PWatchVar var:mWatchVars) {
|
beginResetModel();
|
||||||
if (gdbIndex == var->gdbIndex) {
|
foreach (PWatchVar var, mWatchVars) {
|
||||||
return var;
|
var->name.clear();
|
||||||
|
var->value = tr("Not Valid");
|
||||||
|
var->numChild = 0;
|
||||||
|
var->hasMore = false;
|
||||||
|
var->type.clear();
|
||||||
|
var->children.clear();
|
||||||
}
|
}
|
||||||
|
mVarIndex.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchModel::updateVarInfo(const QString &expression, const QString &name, int numChild, const QString &value, const QString &type, bool hasMore)
|
||||||
|
{
|
||||||
|
PWatchVar var = findWatchVar(expression);
|
||||||
|
if (!var)
|
||||||
|
return;
|
||||||
|
var->name = name;
|
||||||
|
var->value = value;
|
||||||
|
var->numChild = numChild;
|
||||||
|
var->hasMore = hasMore;
|
||||||
|
var->type = type;
|
||||||
|
mVarIndex.insert(name,var);
|
||||||
|
QModelIndex idx = index(var);
|
||||||
|
if (!idx.isValid())
|
||||||
|
return;
|
||||||
|
emit dataChanged(idx,createIndex(idx.row(),2,var.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchModel::prepareVarChildren(const QString &parentName, int numChild, bool hasMore)
|
||||||
|
{
|
||||||
|
PWatchVar var = mVarIndex.value(parentName,PWatchVar());
|
||||||
|
if (var) {
|
||||||
|
var->numChild = numChild;
|
||||||
|
var->hasMore = hasMore;
|
||||||
}
|
}
|
||||||
return PWatchVar();
|
}
|
||||||
|
|
||||||
|
void WatchModel::addVarChild(const QString &parentName, const QString &name,
|
||||||
|
const QString &exp, int numChild, const QString &value,
|
||||||
|
const QString &type, bool hasMore)
|
||||||
|
{
|
||||||
|
PWatchVar var = mVarIndex.value(parentName,PWatchVar());
|
||||||
|
if (!var)
|
||||||
|
return;
|
||||||
|
beginInsertRows(index(var),var->children.count(),var->children.count());
|
||||||
|
PWatchVar child = std::make_shared<WatchVar>();
|
||||||
|
child->name = name;
|
||||||
|
child->expression = exp;
|
||||||
|
child->numChild = numChild;
|
||||||
|
child->value = value;
|
||||||
|
child->type = type;
|
||||||
|
child->hasMore = hasMore;
|
||||||
|
child->parent = var.get();
|
||||||
|
var->children.append(child);
|
||||||
|
endInsertRows();
|
||||||
|
mVarIndex.insert(name,child);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchModel::updateVarValue(const QString &name, const QString &val, const QString &inScope, bool typeChanged, const QString &newType, int newNumChildren, bool hasMore)
|
||||||
|
{
|
||||||
|
PWatchVar var = mVarIndex.value(name,PWatchVar());
|
||||||
|
if (!var)
|
||||||
|
return;
|
||||||
|
if (inScope == "true") {
|
||||||
|
var->value = val;
|
||||||
|
} else{
|
||||||
|
var->value = tr("Not Valid");
|
||||||
|
}
|
||||||
|
if (typeChanged) {
|
||||||
|
var->type = newType;
|
||||||
|
}
|
||||||
|
QModelIndex idx = index(var);
|
||||||
|
if (newNumChildren>=0
|
||||||
|
&& var->numChild!=newNumChildren) {
|
||||||
|
beginRemoveRows(idx,0,var->children.count());
|
||||||
|
var->children.clear();
|
||||||
|
endRemoveRows();
|
||||||
|
var->numChild = newNumChildren;
|
||||||
|
}
|
||||||
|
var->hasMore = hasMore;
|
||||||
|
emit dataChanged(idx,createIndex(idx.row(),2,var.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchModel::clearAllVarInfos()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
foreach (PWatchVar var, mWatchVars) {
|
||||||
|
var->name.clear();
|
||||||
|
var->value = tr("Execute to evaluate");
|
||||||
|
var->numChild = 0;
|
||||||
|
var->hasMore = false;
|
||||||
|
var->type.clear();
|
||||||
|
var->children.clear();
|
||||||
|
}
|
||||||
|
mVarIndex.clear();
|
||||||
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchModel::beginUpdate()
|
void WatchModel::beginUpdate()
|
||||||
|
@ -2036,6 +1997,7 @@ void WatchModel::load(const QString &filename)
|
||||||
var->value = tr("Execute to evaluate");
|
var->value = tr("Execute to evaluate");
|
||||||
var->numChild = 0;
|
var->numChild = 0;
|
||||||
var->hasMore=false;
|
var->hasMore=false;
|
||||||
|
var->parent = nullptr;
|
||||||
|
|
||||||
addWatchVar(var);
|
addWatchVar(var);
|
||||||
}
|
}
|
||||||
|
@ -2045,6 +2007,41 @@ void WatchModel::load(const QString &filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QModelIndex WatchModel::index(PWatchVar var) const
|
||||||
|
{
|
||||||
|
if (!var)
|
||||||
|
return QModelIndex();
|
||||||
|
return index(var.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex WatchModel::index(WatchVar* pVar) const {
|
||||||
|
if (pVar==nullptr)
|
||||||
|
return QModelIndex();
|
||||||
|
if (pVar->parent) {
|
||||||
|
int row=-1;
|
||||||
|
for (int i=0;i<pVar->parent->children.count();i++) {
|
||||||
|
if (pVar->parent->children[i].get() == pVar) {
|
||||||
|
row = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (row<0)
|
||||||
|
return QModelIndex();
|
||||||
|
return createIndex(row,0,pVar);
|
||||||
|
} else {
|
||||||
|
int row=-1;
|
||||||
|
for (int i=0;i<mWatchVars.count();i++) {
|
||||||
|
if (mWatchVars[i].get() == pVar) {
|
||||||
|
row = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (row<0)
|
||||||
|
return QModelIndex();
|
||||||
|
return createIndex(row,0,pVar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QVariant WatchModel::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant WatchModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
{
|
{
|
||||||
|
@ -2063,7 +2060,13 @@ QVariant WatchModel::headerData(int section, Qt::Orientation orientation, int ro
|
||||||
|
|
||||||
void WatchModel::fetchMore(const QModelIndex &parent)
|
void WatchModel::fetchMore(const QModelIndex &parent)
|
||||||
{
|
{
|
||||||
//todo
|
if (!parent.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WatchVar* item = static_cast<WatchVar*>(parent.internalPointer());
|
||||||
|
item->hasMore = false;
|
||||||
|
item->numChild = item->children.count();
|
||||||
|
emit fetchChildren(item->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WatchModel::canFetchMore(const QModelIndex &parent) const
|
bool WatchModel::canFetchMore(const QModelIndex &parent) const
|
||||||
|
@ -2072,13 +2075,13 @@ bool WatchModel::canFetchMore(const QModelIndex &parent) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
WatchVar* item = static_cast<WatchVar*>(parent.internalPointer());
|
WatchVar* item = static_cast<WatchVar*>(parent.internalPointer());
|
||||||
return item->numChild>item->children.count();
|
return item->numChild>item->children.count() || item->hasMore;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WatchModel::hasChildren(const QModelIndex &parent) const
|
bool WatchModel::hasChildren(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
WatchVar* item = static_cast<WatchVar*>(parent.internalPointer());
|
WatchVar* item = static_cast<WatchVar*>(parent.internalPointer());
|
||||||
return item->numChild>0;
|
return item->numChild>0;
|
||||||
|
|
|
@ -131,34 +131,51 @@ public:
|
||||||
QModelIndex index(int row, int column,
|
QModelIndex index(int row, int column,
|
||||||
const QModelIndex &parent = QModelIndex()) const override;
|
const QModelIndex &parent = QModelIndex()) const override;
|
||||||
QModelIndex parent(const QModelIndex &index) const override;
|
QModelIndex parent(const QModelIndex &index) const override;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
|
void fetchMore(const QModelIndex &parent) override;
|
||||||
|
bool canFetchMore(const QModelIndex &parent) const override;
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
bool hasChildren(const QModelIndex &parent) const override;
|
||||||
void addWatchVar(PWatchVar watchVar);
|
void addWatchVar(PWatchVar watchVar);
|
||||||
void removeWatchVar(const QString& expression);
|
void removeWatchVar(const QString& expression);
|
||||||
void removeWatchVar(const QModelIndex& index);
|
void removeWatchVar(const QModelIndex& index);
|
||||||
void clear();
|
void clear();
|
||||||
const QList<PWatchVar>& watchVars();
|
const QList<PWatchVar>& watchVars();
|
||||||
PWatchVar findWatchVar(const QString& name);
|
PWatchVar findWatchVar(const QModelIndex& index);
|
||||||
PWatchVar findWatchVar(int gdbIndex);
|
PWatchVar findWatchVar(const QString& expr);
|
||||||
|
void resetAllVarInfos();
|
||||||
|
void clearAllVarInfos();
|
||||||
void beginUpdate();
|
void beginUpdate();
|
||||||
void endUpdate();
|
void endUpdate();
|
||||||
void notifyUpdated(PWatchVar var);
|
void notifyUpdated(PWatchVar var);
|
||||||
void save(const QString& filename);
|
void save(const QString& filename);
|
||||||
void load(const QString& filename);
|
void load(const QString& filename);
|
||||||
|
public slots:
|
||||||
|
void updateVarInfo(const QString& expression,
|
||||||
|
const QString& name,
|
||||||
|
int numChild,
|
||||||
|
const QString& value,
|
||||||
|
const QString& type,
|
||||||
|
bool hasMore);
|
||||||
|
void prepareVarChildren(const QString& parentName, int numChild, bool hasMore);
|
||||||
|
void addVarChild(const QString& parentName, const QString& name,
|
||||||
|
const QString& exp, int numChild,
|
||||||
|
const QString& value, const QString& type,
|
||||||
|
bool hasMore);
|
||||||
|
void updateVarValue(const QString& name, const QString& val,
|
||||||
|
const QString& inScope, bool typeChanged,
|
||||||
|
const QString& newType, int newNumChildren,
|
||||||
|
bool hasMore);
|
||||||
|
signals:
|
||||||
|
void fetchChildren(const QString& name);
|
||||||
|
private:
|
||||||
|
QModelIndex index(PWatchVar var) const;
|
||||||
|
QModelIndex index(WatchVar* pVar) const;
|
||||||
private:
|
private:
|
||||||
QList<PWatchVar> mWatchVars;
|
QList<PWatchVar> mWatchVars;
|
||||||
|
QHash<QString,PWatchVar> mVarIndex;
|
||||||
int mUpdateCount;
|
int mUpdateCount;
|
||||||
|
|
||||||
// QAbstractItemModel interface
|
|
||||||
public:
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
|
||||||
void fetchMore(const QModelIndex &parent);
|
|
||||||
bool canFetchMore(const QModelIndex &parent) const;
|
|
||||||
|
|
||||||
// QAbstractItemModel interface
|
|
||||||
public:
|
|
||||||
bool hasChildren(const QModelIndex &parent) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -192,25 +209,16 @@ public:
|
||||||
PBreakpoint breakpointAt(int line, const Editor* editor, int &index);
|
PBreakpoint breakpointAt(int line, const Editor* editor, int &index);
|
||||||
void setBreakPointCondition(int index, const QString& condition);
|
void setBreakPointCondition(int index, const QString& condition);
|
||||||
void sendAllBreakpointsToDebugger();
|
void sendAllBreakpointsToDebugger();
|
||||||
void validateBreakpoint(int line, const QString& filename, int number);
|
|
||||||
void invalidateAllBreakpoints();
|
|
||||||
|
|
||||||
//watch vars
|
//watch vars
|
||||||
void addWatchVar(const QString& namein);
|
void addWatchVar(const QString& expression);
|
||||||
// void removeWatchVar(nodein: TTreeNode); overload;
|
void modifyWatchVarExpression(const QString& oldExpr, const QString& newExpr);
|
||||||
void renameWatchVar(const QString& oldname, const QString& newname);
|
|
||||||
|
|
||||||
void refreshWatchVars();
|
|
||||||
void removeWatchVars(bool deleteparent);
|
void removeWatchVars(bool deleteparent);
|
||||||
void removeWatchVar(const QModelIndex& index);
|
void removeWatchVar(const QModelIndex& index);
|
||||||
void invalidateAllVars();
|
void sendAllWatchVarsToDebugger();
|
||||||
void sendAllWatchvarsToDebugger();
|
PWatchVar findWatchVar(const QString& expression);
|
||||||
void invalidateWatchVar(const QString& name);
|
|
||||||
void invalidateWatchVar(PWatchVar var);
|
|
||||||
PWatchVar findWatchVar(const QString& name);
|
|
||||||
// void notifyWatchVarUpdated(PWatchVar var);
|
// void notifyWatchVarUpdated(PWatchVar var);
|
||||||
void notifyBeforeProcessWatchVar();
|
|
||||||
void notifyAfterProcessWatchVar();
|
|
||||||
|
|
||||||
BacktraceModel* backtraceModel();
|
BacktraceModel* backtraceModel();
|
||||||
BreakpointModel* breakpointModel();
|
BreakpointModel* breakpointModel();
|
||||||
|
@ -246,7 +254,8 @@ private slots:
|
||||||
void clearUpReader();
|
void clearUpReader();
|
||||||
void updateRegisterNames(const QStringList& registerNames);
|
void updateRegisterNames(const QStringList& registerNames);
|
||||||
void updateRegisterValues(const QHash<int,QString>& values);
|
void updateRegisterValues(const QHash<int,QString>& values);
|
||||||
|
void refreshWatchVars();
|
||||||
|
void fetchVarChildren(const QString& varName);
|
||||||
private:
|
private:
|
||||||
bool mExecuting;
|
bool mExecuting;
|
||||||
bool mCommandChanged;
|
bool mCommandChanged;
|
||||||
|
@ -272,9 +281,6 @@ public:
|
||||||
bool commandRunning();
|
bool commandRunning();
|
||||||
void waitStart();
|
void waitStart();
|
||||||
|
|
||||||
bool invalidateAllVars() const;
|
|
||||||
void setInvalidateAllVars(bool invalidateAllVars);
|
|
||||||
|
|
||||||
bool inferiorPaused() const;
|
bool inferiorPaused() const;
|
||||||
|
|
||||||
bool processExited() const;
|
bool processExited() const;
|
||||||
|
@ -332,11 +338,24 @@ signals:
|
||||||
void disassemblyUpdate(const QString& filename, const QString& funcName, const QStringList& result);
|
void disassemblyUpdate(const QString& filename, const QString& funcName, const QStringList& result);
|
||||||
void registerNamesUpdated(const QStringList& registerNames);
|
void registerNamesUpdated(const QStringList& registerNames);
|
||||||
void registerValuesUpdated(const QHash<int,QString>& values);
|
void registerValuesUpdated(const QHash<int,QString>& values);
|
||||||
|
void varCreated(const QString& expression,
|
||||||
|
const QString& name,
|
||||||
|
int numChild,
|
||||||
|
const QString& value,
|
||||||
|
const QString& type,
|
||||||
|
bool hasMore);
|
||||||
|
void prepareVarChildren(const QString& parentName,int numChild, bool hasMore);
|
||||||
|
void addVarChild(const QString& parentName, const QString& name,
|
||||||
|
const QString& exp, int numChild,
|
||||||
|
const QString& value, const QString& type,
|
||||||
|
bool hasMore);
|
||||||
|
void varValueUpdated(const QString& name, const QString& val,
|
||||||
|
const QString& inScope, bool typeChanged,
|
||||||
|
const QString& newType, int newNumChildren,
|
||||||
|
bool hasMore);
|
||||||
private:
|
private:
|
||||||
void clearCmdQueue();
|
void clearCmdQueue();
|
||||||
|
|
||||||
QString processEvalOutput();
|
|
||||||
void processWatchOutput(PWatchVar WatchVar);
|
|
||||||
void runNextCmd();
|
void runNextCmd();
|
||||||
QStringList tokenize(const QString& s);
|
QStringList tokenize(const QString& s);
|
||||||
|
|
||||||
|
@ -348,6 +367,9 @@ private:
|
||||||
void handleMemory(const QList<GDBMIResultParser::ParseValue> & rows);
|
void handleMemory(const QList<GDBMIResultParser::ParseValue> & rows);
|
||||||
void handleRegisterNames(const QList<GDBMIResultParser::ParseValue> & names);
|
void handleRegisterNames(const QList<GDBMIResultParser::ParseValue> & names);
|
||||||
void handleRegisterValue(const QList<GDBMIResultParser::ParseValue> & values);
|
void handleRegisterValue(const QList<GDBMIResultParser::ParseValue> & values);
|
||||||
|
void handleCreateVar(const GDBMIResultParser::ParseObject& multiVars);
|
||||||
|
void handleListVarChildren(const GDBMIResultParser::ParseObject& multiVars);
|
||||||
|
void handleUpdateVarValue(const QList<GDBMIResultParser::ParseValue> &changes);
|
||||||
void processConsoleOutput(const QByteArray& line);
|
void processConsoleOutput(const QByteArray& line);
|
||||||
void processResult(const QByteArray& result);
|
void processResult(const QByteArray& result);
|
||||||
void processExecAsyncRecord(const QByteArray& line);
|
void processExecAsyncRecord(const QByteArray& line);
|
||||||
|
@ -362,7 +384,6 @@ private:
|
||||||
QRecursiveMutex mCmdQueueMutex;
|
QRecursiveMutex mCmdQueueMutex;
|
||||||
QSemaphore mStartSemaphore;
|
QSemaphore mStartSemaphore;
|
||||||
QQueue<PDebugCommand> mCmdQueue;
|
QQueue<PDebugCommand> mCmdQueue;
|
||||||
bool mInvalidateAllVars;
|
|
||||||
|
|
||||||
//fOnInvalidateAllVars: TInvalidateAllVarsEvent;
|
//fOnInvalidateAllVars: TInvalidateAllVarsEvent;
|
||||||
bool mCmdRunning;
|
bool mCmdRunning;
|
||||||
|
|
|
@ -18,6 +18,9 @@ GDBMIResultParser::GDBMIResultParser()
|
||||||
mResultTypes.insert("-data-read-memory",GDBMIResultType::Memory);
|
mResultTypes.insert("-data-read-memory",GDBMIResultType::Memory);
|
||||||
mResultTypes.insert("-data-list-register-names",GDBMIResultType::RegisterNames);
|
mResultTypes.insert("-data-list-register-names",GDBMIResultType::RegisterNames);
|
||||||
mResultTypes.insert("-data-list-register-values",GDBMIResultType::RegisterValues);
|
mResultTypes.insert("-data-list-register-values",GDBMIResultType::RegisterValues);
|
||||||
|
mResultTypes.insert("-var-create",GDBMIResultType::CreateVar);
|
||||||
|
mResultTypes.insert("-var-list-children",GDBMIResultType::ListVarChildren);
|
||||||
|
mResultTypes.insert("-var-update",GDBMIResultType::UpdateVarValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GDBMIResultParser::parse(const QByteArray &record, const QString& command, GDBMIResultType &type, ParseObject& multiValues)
|
bool GDBMIResultParser::parse(const QByteArray &record, const QString& command, GDBMIResultType &type, ParseObject& multiValues)
|
||||||
|
@ -290,6 +293,8 @@ bool GDBMIResultParser::isNameChar(char ch)
|
||||||
{
|
{
|
||||||
if (ch=='-')
|
if (ch=='-')
|
||||||
return true;
|
return true;
|
||||||
|
if (ch=='_')
|
||||||
|
return true;
|
||||||
if (ch>='a' && ch<='z')
|
if (ch>='a' && ch<='z')
|
||||||
return true;
|
return true;
|
||||||
if (ch>='A' && ch<='Z')
|
if (ch>='A' && ch<='Z')
|
||||||
|
@ -315,19 +320,16 @@ void GDBMIResultParser::skipSpaces(const char *&p)
|
||||||
|
|
||||||
const QByteArray &GDBMIResultParser::ParseValue::value() const
|
const QByteArray &GDBMIResultParser::ParseValue::value() const
|
||||||
{
|
{
|
||||||
Q_ASSERT(mType == ParseValueType::Value);
|
|
||||||
return mValue;
|
return mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<::GDBMIResultParser::ParseValue> &GDBMIResultParser::ParseValue::array() const
|
const QList<::GDBMIResultParser::ParseValue> &GDBMIResultParser::ParseValue::array() const
|
||||||
{
|
{
|
||||||
Q_ASSERT(mType == ParseValueType::Array);
|
|
||||||
return mArray;
|
return mArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GDBMIResultParser::ParseObject &GDBMIResultParser::ParseValue::object() const
|
const GDBMIResultParser::ParseObject &GDBMIResultParser::ParseValue::object() const
|
||||||
{
|
{
|
||||||
Q_ASSERT(mType == ParseValueType::Object);
|
|
||||||
return mObject;
|
return mObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,9 @@ enum class GDBMIResultType {
|
||||||
RegisterNames,
|
RegisterNames,
|
||||||
RegisterValues,
|
RegisterValues,
|
||||||
Memory,
|
Memory,
|
||||||
VariableInfo,
|
CreateVar,
|
||||||
|
ListVarChildren,
|
||||||
|
UpdateVarValue
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1444,10 +1444,6 @@ void MainWindow::debug()
|
||||||
includeOrSkipDirs(compilerSet->defaultCppIncludeDirs(),true);
|
includeOrSkipDirs(compilerSet->defaultCppIncludeDirs(),true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add breakpoints and watch vars
|
|
||||||
// for i := 0 to fDebugger.WatchVarList.Count - 1 do
|
|
||||||
// fDebugger.AddWatchVar(i);
|
|
||||||
mDebugger->sendAllWatchvarsToDebugger();
|
|
||||||
mDebugger->sendAllBreakpointsToDebugger();
|
mDebugger->sendAllBreakpointsToDebugger();
|
||||||
|
|
||||||
// Run the debugger
|
// Run the debugger
|
||||||
|
@ -1677,10 +1673,10 @@ void MainWindow::includeOrSkipDirs(const QStringList &dirs, bool skip)
|
||||||
foreach (QString dir,dirs) {
|
foreach (QString dir,dirs) {
|
||||||
QString dirName = dir.replace('\\','/');
|
QString dirName = dir.replace('\\','/');
|
||||||
if (skip) {
|
if (skip) {
|
||||||
// mDebugger->sendCommand(
|
mDebugger->sendCommand(
|
||||||
// "skip",
|
"skip",
|
||||||
// QString("-gfi \"%1/%2\"")
|
QString("-gfi \"%1/%2\"")
|
||||||
// .arg(dirName,"*.*"));
|
.arg(dirName,"*.*"));
|
||||||
} else {
|
} else {
|
||||||
mDebugger->sendCommand(
|
mDebugger->sendCommand(
|
||||||
"-environment-directory",
|
"-environment-directory",
|
||||||
|
@ -4001,7 +3997,6 @@ void MainWindow::on_actionStep_Over_triggered()
|
||||||
{
|
{
|
||||||
if (mDebugger->executing()) {
|
if (mDebugger->executing()) {
|
||||||
//WatchView.Items.BeginUpdate();
|
//WatchView.Items.BeginUpdate();
|
||||||
mDebugger->invalidateAllVars();
|
|
||||||
mDebugger->sendCommand("-exec-next", "");
|
mDebugger->sendCommand("-exec-next", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4010,7 +4005,6 @@ void MainWindow::on_actionStep_Into_triggered()
|
||||||
{
|
{
|
||||||
if (mDebugger->executing()) {
|
if (mDebugger->executing()) {
|
||||||
//WatchView.Items.BeginUpdate();
|
//WatchView.Items.BeginUpdate();
|
||||||
mDebugger->invalidateAllVars();
|
|
||||||
mDebugger->sendCommand("-exec-step", "");
|
mDebugger->sendCommand("-exec-step", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4020,7 +4014,6 @@ void MainWindow::on_actionStep_Out_triggered()
|
||||||
{
|
{
|
||||||
if (mDebugger->executing()) {
|
if (mDebugger->executing()) {
|
||||||
//WatchView.Items.BeginUpdate();
|
//WatchView.Items.BeginUpdate();
|
||||||
mDebugger->invalidateAllVars();
|
|
||||||
mDebugger->sendCommand("-exec-finish", "");
|
mDebugger->sendCommand("-exec-finish", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4032,7 +4025,6 @@ void MainWindow::on_actionRun_To_Cursor_triggered()
|
||||||
Editor *e=mEditorList->getEditor();
|
Editor *e=mEditorList->getEditor();
|
||||||
if (e!=nullptr) {
|
if (e!=nullptr) {
|
||||||
//WatchView.Items.BeginUpdate();
|
//WatchView.Items.BeginUpdate();
|
||||||
mDebugger->invalidateAllVars();
|
|
||||||
mDebugger->sendCommand("-exec-until", QString("\"%1\":%2")
|
mDebugger->sendCommand("-exec-until", QString("\"%1\":%2")
|
||||||
.arg(e->filename())
|
.arg(e->filename())
|
||||||
.arg(e->caretY()));
|
.arg(e->caretY()));
|
||||||
|
@ -4045,7 +4037,6 @@ void MainWindow::on_actionContinue_triggered()
|
||||||
{
|
{
|
||||||
if (mDebugger->executing()) {
|
if (mDebugger->executing()) {
|
||||||
//WatchView.Items.BeginUpdate();
|
//WatchView.Items.BeginUpdate();
|
||||||
mDebugger->invalidateAllVars();
|
|
||||||
mDebugger->sendCommand("-exec-continue", "");
|
mDebugger->sendCommand("-exec-continue", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
<enum>QTabWidget::West</enum>
|
<enum>QTabWidget::West</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>3</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="usesScrollButtons">
|
<property name="usesScrollButtons">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -174,7 +174,7 @@
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="headerDefaultSectionSize">
|
<attribute name="headerDefaultSectionSize">
|
||||||
<number>50</number>
|
<number>100</number>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#define DEVCPP_VERSION "beta.0.9.3"
|
#define DEVCPP_VERSION "beta.0.10.0"
|
||||||
|
|
||||||
#endif // VERSION_H
|
#endif // VERSION_H
|
||||||
|
|
Loading…
Reference in New Issue