work save
This commit is contained in:
parent
fdfa7c779f
commit
b17406eb07
|
@ -70,9 +70,14 @@ bool Debugger::start()
|
||||||
&BreakpointModel::updateBreakpointNumber);
|
&BreakpointModel::updateBreakpointNumber);
|
||||||
connect(mReader, &DebugReader::localsUpdated, pMainWindow,
|
connect(mReader, &DebugReader::localsUpdated, pMainWindow,
|
||||||
&MainWindow::onLocalsReady);
|
&MainWindow::onLocalsReady);
|
||||||
connect(mReader, &DebugReader::memoryUpdated,[this](const QStringList memory) {
|
connect(mReader, &DebugReader::memoryUpdated,[this](const QStringList& memory) {
|
||||||
emit memoryExamineReady(memory);
|
emit memoryExamineReady(memory);
|
||||||
});
|
});
|
||||||
|
connect(mReader, &DebugReader::evalUpdated,[this](const QString& value) {
|
||||||
|
emit evalValueReady(value);
|
||||||
|
});
|
||||||
|
connect(mReader, &DebugReader::inferiorStopped,pMainWindow,
|
||||||
|
&MainWindow::setActiveBreakpoint);
|
||||||
|
|
||||||
mReader->start();
|
mReader->start();
|
||||||
mReader->waitStart();
|
mReader->waitStart();
|
||||||
|
@ -133,10 +138,10 @@ WatchModel *Debugger::watchModel() const
|
||||||
return mWatchModel;
|
return mWatchModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::sendCommand(const QString &command, const QString ¶ms, bool updateWatch, bool showInConsole, DebugCommandSource source)
|
void Debugger::sendCommand(const QString &command, const QString ¶ms, DebugCommandSource source)
|
||||||
{
|
{
|
||||||
if (mExecuting && mReader) {
|
if (mExecuting && mReader) {
|
||||||
mReader->postCommand(command,params,updateWatch,showInConsole,source);
|
mReader->postCommand(command,params,source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,60 +468,41 @@ void Debugger::syncFinishedParsing()
|
||||||
}
|
}
|
||||||
|
|
||||||
// show command output
|
// show command output
|
||||||
if (pSettings->debugger().showCommandLog() ||
|
if (pSettings->debugger().showCommandLog() ) {
|
||||||
(mReader->mCurrentCmd && mReader->mCurrentCmd->showInConsole)) {
|
|
||||||
if (pSettings->debugger().showAnnotations()) {
|
if (pSettings->debugger().showAnnotations()) {
|
||||||
QString strOutput = mReader->mOutput;
|
for (const QString& line:mReader->fullOutput()) {
|
||||||
strOutput.replace(QChar(26),'>');
|
pMainWindow->addDebugOutput(line);
|
||||||
pMainWindow->addDebugOutput(strOutput);
|
|
||||||
pMainWindow->addDebugOutput("");
|
|
||||||
pMainWindow->addDebugOutput("");
|
|
||||||
} else {
|
|
||||||
QStringList strList = textToLines(mReader->mOutput);
|
|
||||||
QStringList outStrList;
|
|
||||||
bool addToLastLine=false;
|
|
||||||
for (int i=0;i<strList.size();i++) {
|
|
||||||
QString strOutput=strList[i];
|
|
||||||
if (strOutput.startsWith("\032\032")) {
|
|
||||||
addToLastLine = true;
|
|
||||||
} else {
|
|
||||||
if (addToLastLine && outStrList.size()>0) {
|
|
||||||
outStrList[outStrList.size()-1]+=strOutput;
|
|
||||||
} else {
|
|
||||||
outStrList.append(strOutput);
|
|
||||||
}
|
}
|
||||||
addToLastLine = false;
|
} else {
|
||||||
}
|
for (const QString& line:mReader->consoleOutput()) {
|
||||||
}
|
|
||||||
for (const QString& line:outStrList) {
|
|
||||||
pMainWindow->addDebugOutput(line);
|
pMainWindow->addDebugOutput(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some part of the CPU form has been updated
|
// Some part of the CPU form has been updated
|
||||||
if (pMainWindow->cpuDialog()!=nullptr && !mReader->doreceivedsignal) {
|
if (pMainWindow->cpuDialog()!=nullptr && !mReader->signalReceived()) {
|
||||||
if (mReader->doregistersready) {
|
// if (mReader->doregistersready) {
|
||||||
mRegisterModel->update(mReader->mRegisters);
|
// mRegisterModel->update(mReader->mRegisters);
|
||||||
mReader->mRegisters.clear();
|
// mReader->mRegisters.clear();
|
||||||
mReader->doregistersready = false;
|
// mReader->doregistersready = false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (mReader->dodisassemblerready) {
|
||||||
|
// pMainWindow->cpuDialog()->setDisassembly(mReader->mDisassembly);
|
||||||
|
// mReader->mDisassembly.clear();
|
||||||
|
// mReader->dodisassemblerready = false;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mReader->dodisassemblerready) {
|
// if (mReader->updateExecution()) {
|
||||||
pMainWindow->cpuDialog()->setDisassembly(mReader->mDisassembly);
|
// if (mReader->currentCmd() && mReader->currentCmd()->source == DebugCommandSource::Console) {
|
||||||
mReader->mDisassembly.clear();
|
// pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine(),false);
|
||||||
mReader->dodisassemblerready = false;
|
// } else {
|
||||||
}
|
// pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine());
|
||||||
}
|
// }
|
||||||
|
// refreshWatchVars(); // update variable information
|
||||||
if (mReader->updateExecution()) {
|
// }
|
||||||
if (mReader->currentCmd() && mReader->currentCmd()->source == DebugCommandSource::Console) {
|
|
||||||
pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine(),false);
|
|
||||||
} else {
|
|
||||||
pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine());
|
|
||||||
}
|
|
||||||
refreshWatchVars(); // update variable information
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mReader->signalReceived()) {
|
if (mReader->signalReceived()) {
|
||||||
|
|
||||||
|
@ -588,475 +574,33 @@ DebugReader::DebugReader(Debugger* debugger, QObject *parent) : QThread(parent),
|
||||||
mInvalidateAllVars = false;
|
mInvalidateAllVars = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugReader::postCommand(const QString &Command, const QString &Params, bool UpdateWatch, bool ShowInConsole, DebugCommandSource Source)
|
void DebugReader::postCommand(const QString &Command, const QString &Params,
|
||||||
|
DebugCommandSource Source)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mCmdQueueMutex);
|
QMutexLocker locker(&mCmdQueueMutex);
|
||||||
if (mCmdQueue.isEmpty() && UpdateWatch) {
|
|
||||||
emit pauseWatchUpdate();
|
|
||||||
mUpdateCount++;
|
|
||||||
}
|
|
||||||
PDebugCommand pCmd = std::make_shared<DebugCommand>();
|
PDebugCommand pCmd = std::make_shared<DebugCommand>();
|
||||||
pCmd->command = Command;
|
pCmd->command = Command;
|
||||||
pCmd->params = Params;
|
pCmd->params = Params;
|
||||||
pCmd->updateWatch = UpdateWatch;
|
|
||||||
pCmd->showInConsole = ShowInConsole;
|
|
||||||
pCmd->source = Source;
|
pCmd->source = Source;
|
||||||
mCmdQueue.enqueue(pCmd);
|
mCmdQueue.enqueue(pCmd);
|
||||||
// if (!mCmdRunning)
|
// if (!mCmdRunning)
|
||||||
// runNextCmd();
|
// runNextCmd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugReader::registerInferiorStoppedCommand(const QString &Command, const QString &Params)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mCmdQueueMutex);
|
||||||
|
PDebugCommand pCmd = std::make_shared<DebugCommand>();
|
||||||
|
pCmd->command = Command;
|
||||||
|
pCmd->params = Params;
|
||||||
|
pCmd->source = DebugCommandSource::Other;
|
||||||
|
mInferiorStoppedHookCommands.append(pCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugReader::clearCmdQueue()
|
void DebugReader::clearCmdQueue()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mCmdQueueMutex);
|
QMutexLocker locker(&mCmdQueueMutex);
|
||||||
mCmdQueue.clear();
|
mCmdQueue.clear();
|
||||||
|
|
||||||
if (mUpdateCount>0) {
|
|
||||||
emit updateWatch();
|
|
||||||
mUpdateCount=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebugReader::findAnnotation(AnnotationType annotation)
|
|
||||||
{
|
|
||||||
AnnotationType NextAnnotation;
|
|
||||||
do {
|
|
||||||
NextAnnotation = getNextAnnotation();
|
|
||||||
if (NextAnnotation == AnnotationType::TEOF)
|
|
||||||
return false;
|
|
||||||
} while (NextAnnotation != annotation);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
AnnotationType DebugReader::getAnnotation(const QString &s)
|
|
||||||
{
|
|
||||||
if (s == "pre-prompt") {
|
|
||||||
return AnnotationType::TPrePrompt;
|
|
||||||
} else if (s == "prompt") {
|
|
||||||
return AnnotationType::TPrompt;
|
|
||||||
} else if (s == "post-prompt") {
|
|
||||||
AnnotationType result = AnnotationType::TPostPrompt;
|
|
||||||
//hack to catch local
|
|
||||||
if ((mCurrentCmd) && (mCurrentCmd->command == "info locals")) {
|
|
||||||
result = AnnotationType::TLocal;
|
|
||||||
} else if ((mCurrentCmd) && (mCurrentCmd->command == "info args")) {
|
|
||||||
//hack to catch params
|
|
||||||
result = AnnotationType::TParam;
|
|
||||||
} else if ((mCurrentCmd) && (mCurrentCmd->command == "info") && (mCurrentCmd->params=="registers")) {
|
|
||||||
// Hack fix to catch register dump
|
|
||||||
result = AnnotationType::TInfoReg;
|
|
||||||
} else if ((mCurrentCmd) && (mCurrentCmd->command == "disas")) {
|
|
||||||
// Another hack to catch assembler
|
|
||||||
result = AnnotationType::TInfoAsm;
|
|
||||||
} else if ((mCurrentCmd) && (mCurrentCmd->command.startsWith("x/"))) {
|
|
||||||
result = AnnotationType::TMemory;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} else if (s == "error-begin") {
|
|
||||||
return AnnotationType::TErrorBegin;
|
|
||||||
} else if (s == "error-end") {
|
|
||||||
return AnnotationType::TErrorEnd;
|
|
||||||
} else if (s == "display-begin") {
|
|
||||||
return AnnotationType::TDisplayBegin;
|
|
||||||
} else if (s == "display-expression") {
|
|
||||||
return AnnotationType::TDisplayExpression;
|
|
||||||
} else if (s == "display-end") {
|
|
||||||
return AnnotationType::TDisplayEnd;
|
|
||||||
} else if (s == "frame-source-begin") {
|
|
||||||
return AnnotationType::TFrameSourceBegin;
|
|
||||||
} else if (s == "frame-source-file") {
|
|
||||||
return AnnotationType::TFrameSourceFile;
|
|
||||||
} else if (s == "frame-source-line") {
|
|
||||||
return AnnotationType::TFrameSourceLine;
|
|
||||||
} else if (s == "frame-function-name") {
|
|
||||||
return AnnotationType::TFrameFunctionName;
|
|
||||||
} else if (s == "frame-args") {
|
|
||||||
return AnnotationType::TFrameArgs;
|
|
||||||
} else if (s == "frame-begin") {
|
|
||||||
return AnnotationType::TFrameBegin;
|
|
||||||
} else if (s == "frame-end") {
|
|
||||||
return AnnotationType::TFrameEnd;
|
|
||||||
} else if (s == "frame-where") {
|
|
||||||
return AnnotationType::TFrameWhere;
|
|
||||||
} else if (s == "source") {
|
|
||||||
return AnnotationType::TSource;
|
|
||||||
} else if (s == "exited") {
|
|
||||||
return AnnotationType::TExit;
|
|
||||||
} else if (s == "arg-begin") {
|
|
||||||
return AnnotationType::TArgBegin;
|
|
||||||
} else if (s == "arg-name-end") {
|
|
||||||
return AnnotationType::TArgNameEnd;
|
|
||||||
} else if (s == "arg-value") {
|
|
||||||
return AnnotationType::TArgValue;
|
|
||||||
} else if (s == "arg-end") {
|
|
||||||
return AnnotationType::TArgEnd;
|
|
||||||
} else if (s == "array-section-begin") {
|
|
||||||
return AnnotationType::TArrayBegin;
|
|
||||||
} else if (s == "array-section-end") {
|
|
||||||
return AnnotationType::TArrayEnd;
|
|
||||||
} else if (s == "elt") {
|
|
||||||
return AnnotationType::TElt;
|
|
||||||
} else if (s == "elt-rep") {
|
|
||||||
return AnnotationType::TEltRep;
|
|
||||||
} else if (s == "elt-rep-end") {
|
|
||||||
return AnnotationType::TEltRepEnd;
|
|
||||||
} else if (s == "field-begin") {
|
|
||||||
return AnnotationType::TFieldBegin;
|
|
||||||
} else if (s == "field-name-end") {
|
|
||||||
return AnnotationType::TFieldNameEnd;
|
|
||||||
} else if (s == "field-value") {
|
|
||||||
return AnnotationType::TFieldValue;
|
|
||||||
} else if (s == "field-end") {
|
|
||||||
return AnnotationType::TFieldEnd;
|
|
||||||
} else if (s == "value-history-value") {
|
|
||||||
return AnnotationType::TValueHistoryValue;
|
|
||||||
} else if (s == "value-history-begin") {
|
|
||||||
return AnnotationType::TValueHistoryBegin;
|
|
||||||
} else if (s == "value-history-end") {
|
|
||||||
return AnnotationType::TValueHistoryEnd;
|
|
||||||
} else if (s == "signal") {
|
|
||||||
return AnnotationType::TSignal;
|
|
||||||
} else if (s == "signal-name") {
|
|
||||||
return AnnotationType::TSignalName;
|
|
||||||
} else if (s == "signal-name-end") {
|
|
||||||
return AnnotationType::TSignalNameEnd;
|
|
||||||
} else if (s == "signal-string") {
|
|
||||||
return AnnotationType::TSignalString;
|
|
||||||
} else if (s == "signal-string-end") {
|
|
||||||
return AnnotationType::TSignalStringEnd;
|
|
||||||
} else if (mIndex >= mOutput.length()) {
|
|
||||||
return AnnotationType::TEOF;
|
|
||||||
} else {
|
|
||||||
return AnnotationType::TUnknown;;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AnnotationType DebugReader::getLastAnnotation(const QByteArray &text)
|
|
||||||
{
|
|
||||||
int curpos = text.length()-1;
|
|
||||||
// Walk back until end of #26's
|
|
||||||
while ((curpos >= 0) && (text[curpos] != 26))
|
|
||||||
curpos--;
|
|
||||||
|
|
||||||
curpos++;
|
|
||||||
|
|
||||||
// Tiny rewrite of GetNextWord for special purposes
|
|
||||||
QString s = "";
|
|
||||||
while ((curpos < text.length()) && (text[curpos]>32)) {
|
|
||||||
s = s + text[curpos];
|
|
||||||
curpos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getAnnotation(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
AnnotationType DebugReader::getNextAnnotation()
|
|
||||||
{
|
|
||||||
// Skip until end of #26's, i.e. GDB formatted output
|
|
||||||
skipToAnnotation();
|
|
||||||
|
|
||||||
// Get part this line, after #26#26
|
|
||||||
return getAnnotation(getNextWord());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebugReader::outputTerminated(QByteArray &text)
|
|
||||||
{
|
|
||||||
QStringList lines = textToLines(QString::fromUtf8(text));
|
|
||||||
foreach (const QString& line,lines) {
|
|
||||||
if (line == "(gdb)")
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DebugReader::getNextFilledLine()
|
|
||||||
{
|
|
||||||
// Walk up to an enter sequence
|
|
||||||
while (mIndex<mOutput.length() && mOutput[mIndex]!='\r' && mOutput[mIndex]!='\n' && mOutput[mIndex]!=0)
|
|
||||||
mIndex++;
|
|
||||||
// Skip enter sequences (CRLF, CR, LF, etc.)
|
|
||||||
while (mIndex<mOutput.length() && mOutput[mIndex]=='\r' && mOutput[mIndex]=='\n' && mOutput[mIndex]==0)
|
|
||||||
mIndex++;
|
|
||||||
// Return next line
|
|
||||||
return getRemainingLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DebugReader::getNextLine()
|
|
||||||
{
|
|
||||||
// Walk up to an enter sequence
|
|
||||||
while (mIndex<mOutput.length() && mOutput[mIndex]!='\r' && mOutput[mIndex]!='\n' && mOutput[mIndex]!=0)
|
|
||||||
mIndex++;
|
|
||||||
|
|
||||||
// End of output. Exit
|
|
||||||
if (mIndex>=mOutput.length())
|
|
||||||
return "";
|
|
||||||
// Skip ONE enter sequence (CRLF, CR, LF, etc.)
|
|
||||||
if ((mOutput[mIndex] == '\r') && (mIndex+1<mOutput.length()) && (mOutput[mIndex+1] == '\n')) // DOS
|
|
||||||
mIndex+=2;
|
|
||||||
else if (mOutput[mIndex] == '\r') // UNIX
|
|
||||||
mIndex++;
|
|
||||||
else if (mOutput[mIndex] == '\n') // MAC
|
|
||||||
mIndex++;
|
|
||||||
// Return next line
|
|
||||||
return getRemainingLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DebugReader::getNextWord()
|
|
||||||
{
|
|
||||||
QString Result;
|
|
||||||
|
|
||||||
// Called when at a space? Skip over
|
|
||||||
skipSpaces();
|
|
||||||
|
|
||||||
// Skip until a space
|
|
||||||
while (mIndex<mOutput.length() && mOutput[mIndex]>32) {
|
|
||||||
Result += mOutput[mIndex];
|
|
||||||
mIndex++;
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DebugReader::getRemainingLine()
|
|
||||||
{
|
|
||||||
QString Result;
|
|
||||||
|
|
||||||
// Return part of line still ahead of us
|
|
||||||
while (mIndex<mOutput.length() && mOutput[mIndex]!='\r' && mOutput[mIndex]!='\n' && mOutput[mIndex]!=0) {
|
|
||||||
Result += mOutput[mIndex];
|
|
||||||
mIndex++;
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleDisassembly()
|
|
||||||
{
|
|
||||||
// Get info message
|
|
||||||
QString s = getNextLine();
|
|
||||||
|
|
||||||
// the full function name will be saved at index 0
|
|
||||||
mDisassembly.append(s.mid(36));
|
|
||||||
|
|
||||||
s = getNextLine();
|
|
||||||
|
|
||||||
// Add lines of disassembly
|
|
||||||
while (s != "End of assembler dump.") {
|
|
||||||
if(!s.isEmpty())
|
|
||||||
mDisassembly.append(s);
|
|
||||||
s = getNextLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
dodisassemblerready = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleDisplay()
|
|
||||||
{
|
|
||||||
QString s = getNextLine(); // watch index
|
|
||||||
|
|
||||||
if (!findAnnotation(AnnotationType::TDisplayExpression))
|
|
||||||
return;
|
|
||||||
QString watchName = getNextLine(); // watch name
|
|
||||||
// Find watchVar we're talking about
|
|
||||||
PWatchVar watchVar = mDebugger->findWatchVar(watchName);
|
|
||||||
if (watchVar) {
|
|
||||||
// Advance up to the value
|
|
||||||
if (!findAnnotation(AnnotationType::TDisplayExpression))
|
|
||||||
return;;
|
|
||||||
// Refresh GDB index so we can undisplay this by index
|
|
||||||
watchVar->gdbIndex = s.toInt();
|
|
||||||
mDebugger->notifyBeforeProcessWatchVar();
|
|
||||||
processWatchOutput(watchVar);
|
|
||||||
mDebugger->notifyAfterProcessWatchVar();
|
|
||||||
//mDebugger->notifyWatchVarUpdated(watchVar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleError()
|
|
||||||
{
|
|
||||||
QString s = getNextLine(); // error text
|
|
||||||
if (s.startsWith("Cannot find bounds of current function")) {
|
|
||||||
//We have exited
|
|
||||||
handleExit();
|
|
||||||
} else if (s.startsWith("No symbol \"")) {
|
|
||||||
int head = s.indexOf('\"');
|
|
||||||
int tail = s.lastIndexOf('\"');
|
|
||||||
QString watchName = s.mid(head+1, tail-head-1);
|
|
||||||
|
|
||||||
// Update current..
|
|
||||||
mDebugger->invalidateWatchVar(watchName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleExit()
|
|
||||||
{
|
|
||||||
doprocessexited=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleLocalOutput()
|
|
||||||
{
|
|
||||||
// name(spaces)hexvalue(tab)decimalvalue
|
|
||||||
QString s = getNextFilledLine();
|
|
||||||
|
|
||||||
bool nobreakLine = false;
|
|
||||||
QString line;
|
|
||||||
while (true) {
|
|
||||||
if (!s.startsWith("\032\032")) {
|
|
||||||
s = trimLeft(s);
|
|
||||||
if (s == "No locals.") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (s == "No arguments.") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//todo: update local view
|
|
||||||
if (nobreakLine && pMainWindow->txtLocals()->document()->lineCount()>0) {
|
|
||||||
line += s;
|
|
||||||
// emit addLocalWithoutLinebreak(s);
|
|
||||||
} else {
|
|
||||||
mLocalsValue.append(line);
|
|
||||||
line = s;
|
|
||||||
}
|
|
||||||
nobreakLine=false;
|
|
||||||
} else {
|
|
||||||
nobreakLine = true;
|
|
||||||
}
|
|
||||||
s = getNextLine();
|
|
||||||
if (!nobreakLine && s.isEmpty())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!line.isEmpty()) {
|
|
||||||
mLocalsValue.append(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleLocals()
|
|
||||||
{
|
|
||||||
mLocalsValue.clear();
|
|
||||||
handleLocalOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleMemory()
|
|
||||||
{
|
|
||||||
doupdatememoryview = true;
|
|
||||||
// name(spaces)hexvalue(tab)decimalvalue
|
|
||||||
mMemoryValue.clear();
|
|
||||||
QString s = getNextFilledLine();
|
|
||||||
bool isAnnotation = false;
|
|
||||||
while (true) {
|
|
||||||
if (!s.startsWith("\032\032")) {
|
|
||||||
s = s.trimmed();
|
|
||||||
if (!s.isEmpty()) {
|
|
||||||
mMemoryValue.append(s);
|
|
||||||
}
|
|
||||||
isAnnotation = false;
|
|
||||||
} else {
|
|
||||||
isAnnotation = true;
|
|
||||||
}
|
|
||||||
s = getNextLine();
|
|
||||||
if (!isAnnotation && s.isEmpty())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleParams(){
|
|
||||||
handleLocalOutput();
|
|
||||||
doupdatelocal = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleRegisters()
|
|
||||||
{
|
|
||||||
// name(spaces)hexvalue(tab)decimalvalue
|
|
||||||
QString s = getNextFilledLine();
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
PRegister reg = std::make_shared<Register>();
|
|
||||||
// Cut name from 1 to first space
|
|
||||||
int x = s.indexOf(' ');
|
|
||||||
reg->name = s.mid(0,x);
|
|
||||||
s.remove(0,x);
|
|
||||||
// Remove spaces
|
|
||||||
s = trimLeft(s);
|
|
||||||
|
|
||||||
// Cut hex value from 1 to first tab
|
|
||||||
x = s.indexOf('\t');
|
|
||||||
if (x<0)
|
|
||||||
x = s.indexOf(' ');
|
|
||||||
reg->hexValue = s.mid(0,x);
|
|
||||||
s.remove(0,x); // delete tab too
|
|
||||||
s = trimLeft(s);
|
|
||||||
|
|
||||||
// Remaining part contains decimal value
|
|
||||||
reg->decValue = s;
|
|
||||||
|
|
||||||
if (!reg->name.trimmed().isEmpty())
|
|
||||||
mRegisters.append(reg);
|
|
||||||
s = getNextLine();
|
|
||||||
if (s.isEmpty())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
doregistersready = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleSignal()
|
|
||||||
{
|
|
||||||
mSignal = getNextFilledLine(); // Program received signal
|
|
||||||
|
|
||||||
if (!findAnnotation(AnnotationType::TSignalName))
|
|
||||||
return;
|
|
||||||
|
|
||||||
mSignal = mSignal + getNextFilledLine(); // signal code
|
|
||||||
|
|
||||||
if (!findAnnotation(AnnotationType::TSignalNameEnd))
|
|
||||||
return;
|
|
||||||
|
|
||||||
mSignal = mSignal + getNextFilledLine(); // comma
|
|
||||||
|
|
||||||
if (!findAnnotation(AnnotationType::TSignalString))
|
|
||||||
return;
|
|
||||||
|
|
||||||
mSignal = mSignal + getNextFilledLine(); // user friendly description
|
|
||||||
|
|
||||||
if (!findAnnotation(AnnotationType::TSignalStringEnd))
|
|
||||||
return;
|
|
||||||
|
|
||||||
mSignal = mSignal + getNextFilledLine(); // period
|
|
||||||
|
|
||||||
doreceivedsignal = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleSource()
|
|
||||||
{
|
|
||||||
// source filename:line:offset:beg/middle/end:addr
|
|
||||||
QString s = trimLeft(getRemainingLine());
|
|
||||||
|
|
||||||
// remove offset, beg/middle/end, address
|
|
||||||
for (int i=0;i<3;i++) {
|
|
||||||
int delimPos = s.lastIndexOf(':');
|
|
||||||
if (delimPos >= 0)
|
|
||||||
s.remove(delimPos,INT_MAX);
|
|
||||||
else
|
|
||||||
return; // Wrong format. Don't bother to continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// get line
|
|
||||||
int delimPos = s.lastIndexOf(':');
|
|
||||||
if (delimPos >= 0) {
|
|
||||||
mBreakPointLine = s.mid(delimPos+1).toInt();
|
|
||||||
s.remove(delimPos, INT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get file
|
|
||||||
mBreakPointFile = s;
|
|
||||||
|
|
||||||
doupdateexecution = true;
|
|
||||||
doupdatecpuwindow = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebugReader::handleValueHistoryValue()
|
|
||||||
{
|
|
||||||
mEvalValue = processEvalOutput();
|
|
||||||
doevalready = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugReader::processConsoleOutput(const QByteArray& line)
|
void DebugReader::processConsoleOutput(const QByteArray& line)
|
||||||
|
@ -1068,7 +612,6 @@ void DebugReader::processConsoleOutput(const QByteArray& line)
|
||||||
|
|
||||||
void DebugReader::processResult(const QByteArray &result)
|
void DebugReader::processResult(const QByteArray &result)
|
||||||
{
|
{
|
||||||
int pos = result.indexOf('=');
|
|
||||||
GDBMIResultParser parser;
|
GDBMIResultParser parser;
|
||||||
GDBMIResultType resultType;
|
GDBMIResultType resultType;
|
||||||
GDBMIResultParser::ParseValue parseValue;
|
GDBMIResultParser::ParseValue parseValue;
|
||||||
|
@ -1094,35 +637,6 @@ void DebugReader::processResult(const QByteArray &result)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray name = result.mid(0,pos);
|
|
||||||
QByteArray value = result.mid(pos+1);
|
|
||||||
if (name == "bkpt") {
|
|
||||||
// info about breakpoint
|
|
||||||
handleBreakpoint(value);
|
|
||||||
} else if (name == "BreakpointTable") {
|
|
||||||
// info about breakpoint table
|
|
||||||
handleBreakpointTable(value);
|
|
||||||
} else if (name == "stack") {
|
|
||||||
// info about frame stack
|
|
||||||
handleFrameStack(value);
|
|
||||||
} else if (name == "variables") {
|
|
||||||
// info about local variables & arguments
|
|
||||||
handleVariables(value);
|
|
||||||
} else if (name == "frame") {
|
|
||||||
// info about current selected frame
|
|
||||||
handleFrame(value);
|
|
||||||
} else if (name == "asm_insns") {
|
|
||||||
// info about disassembled codes
|
|
||||||
handleDisassembled(value);
|
|
||||||
} else if (name == "value") {
|
|
||||||
handleEval(value);
|
|
||||||
} else if (name=="register-names") {
|
|
||||||
handleRegisterNames(value);
|
|
||||||
} else if (name == "register-values") {
|
|
||||||
handleRegisterValues(value);
|
|
||||||
} else if (name == "memory") {
|
|
||||||
handleMemory(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugReader::processExecAsyncRecord(const QByteArray &line)
|
void DebugReader::processExecAsyncRecord(const QByteArray &line)
|
||||||
|
@ -1132,12 +646,16 @@ void DebugReader::processExecAsyncRecord(const QByteArray &line)
|
||||||
GDBMIResultParser parser;
|
GDBMIResultParser parser;
|
||||||
if (!parser.parseAsyncResult(line,result,multiValues))
|
if (!parser.parseAsyncResult(line,result,multiValues))
|
||||||
return;
|
return;
|
||||||
|
qDebug()<<result<<line;
|
||||||
if (result == "running") {
|
if (result == "running") {
|
||||||
mInferiorRunning = true;
|
mInferiorRunning = true;
|
||||||
|
mCurrentAddress=0;
|
||||||
|
mCurrentFile.clear();
|
||||||
|
mCurrentLine=-1;
|
||||||
emit inferiorContinued();
|
emit inferiorContinued();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (result == "*stopped") {
|
if (result == "stopped") {
|
||||||
mInferiorRunning = false;
|
mInferiorRunning = false;
|
||||||
QByteArray reason = multiValues["reason"].value();
|
QByteArray reason = multiValues["reason"].value();
|
||||||
if (reason == "exited") {
|
if (reason == "exited") {
|
||||||
|
@ -1157,10 +675,22 @@ void DebugReader::processExecAsyncRecord(const QByteArray &line)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mUpdateCPUInfo = true;
|
mUpdateCPUInfo = true;
|
||||||
emit inferiorStopped(multiValues["fullname"].pathValue(), multiValues["line"].intValue());
|
GDBMIResultParser::ParseValue frame(multiValues["frame"]);
|
||||||
|
if (frame.isValid()) {
|
||||||
|
GDBMIResultParser::ParseObject frameObj = frame.object();
|
||||||
|
mCurrentAddress = frameObj["addr"].hexValue();
|
||||||
|
mCurrentLine = frameObj["line"].intValue();
|
||||||
|
mCurrentFile = frameObj["fullname"].pathValue();
|
||||||
|
}
|
||||||
|
qDebug()<<mCurrentFile<<mCurrentLine;
|
||||||
if (reason == "signal-received") {
|
if (reason == "signal-received") {
|
||||||
mSignalReceived = true;
|
mSignalReceived = true;
|
||||||
}
|
}
|
||||||
|
runInferiorStoppedHook();
|
||||||
|
if (mCurrentCmd && mCurrentCmd->source == DebugCommandSource::Console)
|
||||||
|
emit inferiorStopped(mCurrentFile, mCurrentLine,false);
|
||||||
|
else
|
||||||
|
emit inferiorStopped(mCurrentFile, mCurrentLine,true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1208,31 +738,17 @@ void DebugReader::processDebugOutput(const QByteArray& debugOutput)
|
||||||
emit parseStarted();
|
emit parseStarted();
|
||||||
|
|
||||||
mConsoleOutput.clear();
|
mConsoleOutput.clear();
|
||||||
mLocalsValue.clear();
|
mFullOutput.clear();
|
||||||
mEvalValue.clear();
|
|
||||||
mMemoryValue.clear();
|
|
||||||
|
|
||||||
mUpdateExecution = false;
|
|
||||||
mSignalReceived = false;
|
mSignalReceived = false;
|
||||||
mUpdateCPUInfo = false;
|
mUpdateCPUInfo = false;
|
||||||
mUpdateLocals = false;
|
|
||||||
mEvalReady = false;
|
|
||||||
mReceivedSFWarning = false;
|
mReceivedSFWarning = false;
|
||||||
|
|
||||||
dodisassemblerready = false;
|
|
||||||
doregistersready = false;
|
|
||||||
doevalready = false;
|
|
||||||
doupdatememoryview = false;
|
|
||||||
doupdatelocal = false;
|
|
||||||
doupdateexecution = false;
|
|
||||||
doreceivedsignal = false;
|
|
||||||
doupdatecpuwindow = false;
|
|
||||||
doreceivedsfwarning = false;
|
|
||||||
|
|
||||||
QList<QByteArray> lines = splitByteArrayToLines(debugOutput);
|
QList<QByteArray> lines = splitByteArrayToLines(debugOutput);
|
||||||
|
|
||||||
for (int i=0;i<lines.count();i++) {
|
for (int i=0;i<lines.count();i++) {
|
||||||
QByteArray line = lines[i];
|
QByteArray line = lines[i];
|
||||||
|
mFullOutput.append(line);
|
||||||
line = removeToken(line);
|
line = removeToken(line);
|
||||||
if (line.isEmpty()) {
|
if (line.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1259,47 +775,54 @@ void DebugReader::processDebugOutput(const QByteArray& debugOutput)
|
||||||
emit parseFinished();
|
emit parseFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugReader::runInferiorStoppedHook()
|
||||||
|
{
|
||||||
|
foreach (const PDebugCommand& cmd, mInferiorStoppedHookCommands) {
|
||||||
|
mCmdQueue.push_front(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString DebugReader::processEvalOutput()
|
QString DebugReader::processEvalOutput()
|
||||||
{
|
{
|
||||||
int indent = 0;
|
int indent = 0;
|
||||||
|
|
||||||
// First line gets special treatment
|
// First line gets special treatment
|
||||||
QString result = getNextLine();
|
QString result ="";
|
||||||
if (result.startsWith('{'))
|
if (result.startsWith('{'))
|
||||||
indent+=4;
|
indent+=4;
|
||||||
|
|
||||||
// Collect all data, add formatting in between
|
// Collect all data, add formatting in between
|
||||||
AnnotationType nextAnnotation;
|
// AnnotationType nextAnnotation;
|
||||||
QString nextLine;
|
// QString nextLine;
|
||||||
bool shouldExit = false;
|
// bool shouldExit = false;
|
||||||
do {
|
// do {
|
||||||
nextAnnotation = getNextAnnotation();
|
// nextAnnotation = getNextAnnotation();
|
||||||
nextLine = getNextLine();
|
// nextLine = getNextLine();
|
||||||
switch(nextAnnotation) {
|
// switch(nextAnnotation) {
|
||||||
// Change indent if { or } is found
|
// // Change indent if { or } is found
|
||||||
case AnnotationType::TFieldBegin:
|
// case AnnotationType::TFieldBegin:
|
||||||
result += "\r\n" + QString(4,' ');
|
// result += "\r\n" + QString(4,' ');
|
||||||
break;
|
// break;
|
||||||
case AnnotationType::TFieldValue:
|
// case AnnotationType::TFieldValue:
|
||||||
if (nextLine.startsWith('{') && (peekNextAnnotation() !=
|
// if (nextLine.startsWith('{') && (peekNextAnnotation() !=
|
||||||
AnnotationType::TArrayBegin))
|
// AnnotationType::TArrayBegin))
|
||||||
indent+=4;
|
// indent+=4;
|
||||||
break;
|
// break;
|
||||||
case AnnotationType::TFieldEnd:
|
// case AnnotationType::TFieldEnd:
|
||||||
if (nextLine.endsWith('}')) {
|
// if (nextLine.endsWith('}')) {
|
||||||
indent-=4;
|
// indent-=4;
|
||||||
result += "\r\n" + QString(4,' ');
|
// result += "\r\n" + QString(4,' ');
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case AnnotationType::TEOF:
|
// case AnnotationType::TEOF:
|
||||||
case AnnotationType::TValueHistoryEnd:
|
// case AnnotationType::TValueHistoryEnd:
|
||||||
case AnnotationType::TDisplayEnd:
|
// case AnnotationType::TDisplayEnd:
|
||||||
shouldExit = true;
|
// shouldExit = true;
|
||||||
default:
|
// default:
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
result += nextLine;
|
// result += nextLine;
|
||||||
} while (!shouldExit);
|
// } while (!shouldExit);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,33 +968,18 @@ void DebugReader::processWatchOutput(PWatchVar watchVar)
|
||||||
|
|
||||||
void DebugReader::runNextCmd()
|
void DebugReader::runNextCmd()
|
||||||
{
|
{
|
||||||
bool doUpdate=false;
|
|
||||||
|
|
||||||
auto action = finally([this,&doUpdate] {
|
|
||||||
if (doUpdate) {
|
|
||||||
emit updateWatch();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
QMutexLocker locker(&mCmdQueueMutex);
|
QMutexLocker locker(&mCmdQueueMutex);
|
||||||
if (mCmdQueue.isEmpty()) {
|
|
||||||
if ((mCurrentCmd) && (mCurrentCmd->updateWatch)) {
|
|
||||||
doUpdate=true;
|
|
||||||
if (mUpdateCount>0) {
|
|
||||||
mUpdateCount=0;
|
|
||||||
}
|
|
||||||
emit cmdFinished();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCurrentCmd) {
|
if (mCurrentCmd) {
|
||||||
mCurrentCmd.reset();
|
mCurrentCmd.reset();
|
||||||
|
emit cmdFinished();
|
||||||
}
|
}
|
||||||
|
if (mCmdQueue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
PDebugCommand pCmd = mCmdQueue.dequeue();
|
PDebugCommand pCmd = mCmdQueue.dequeue();
|
||||||
mCmdRunning = true;
|
mCmdRunning = true;
|
||||||
mCurrentCmd = pCmd;
|
mCurrentCmd = pCmd;
|
||||||
if (mCurrentCmd->updateWatch)
|
|
||||||
emit cmdStarted();
|
emit cmdStarted();
|
||||||
|
|
||||||
QByteArray s;
|
QByteArray s;
|
||||||
|
@ -1485,20 +993,12 @@ void DebugReader::runNextCmd()
|
||||||
}
|
}
|
||||||
|
|
||||||
// if devDebugger.ShowCommandLog or pCmd^.ShowInConsole then begin
|
// if devDebugger.ShowCommandLog or pCmd^.ShowInConsole then begin
|
||||||
if (pSettings->debugger().showCommandLog() || pCmd->showInConsole) {
|
if (pSettings->debugger().showCommandLog() ) {
|
||||||
//update debug console
|
//update debug console
|
||||||
// if not devDebugger.ShowAnnotations then begin
|
|
||||||
if (!pSettings->debugger().showAnnotations()) {
|
if (!pSettings->debugger().showAnnotations()) {
|
||||||
// if MainForm.DebugOutput.Lines.Count>0 then begin
|
|
||||||
// MainForm.DebugOutput.Lines.Delete(MainForm.DebugOutput.Lines.Count-1);
|
|
||||||
// end;
|
|
||||||
emit changeDebugConsoleLastLine("(gdb)"+pCmd->command + ' ' + pCmd->params);
|
emit changeDebugConsoleLastLine("(gdb)"+pCmd->command + ' ' + pCmd->params);
|
||||||
// MainForm.DebugOutput.Lines.Add('(gdb)'+pCmd^.Cmd + ' ' + pCmd^.params);
|
|
||||||
// MainForm.DebugOutput.Lines.Add('');
|
|
||||||
} else {
|
} else {
|
||||||
emit changeDebugConsoleLastLine("(gdb)"+pCmd->command + ' ' + pCmd->params);
|
emit changeDebugConsoleLastLine("(gdb)"+pCmd->command + ' ' + pCmd->params);
|
||||||
// MainForm.DebugOutput.Lines.Add(pCmd^.Cmd + ' ' + pCmd^.params);
|
|
||||||
// MainForm.DebugOutput.Lines.Add('');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1599,6 +1099,16 @@ QStringList DebugReader::tokenize(const QString &s)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DebugReader::outputTerminated(const QByteArray &text)
|
||||||
|
{
|
||||||
|
QStringList lines = textToLines(QString::fromUtf8(text));
|
||||||
|
foreach (const QString& line,lines) {
|
||||||
|
if (line.trimmed() == "(gdb)")
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void DebugReader::handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint)
|
void DebugReader::handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint)
|
||||||
{
|
{
|
||||||
// gdb use system encoding for file path
|
// gdb use system encoding for file path
|
||||||
|
@ -1670,41 +1180,16 @@ QByteArray DebugReader::removeToken(const QByteArray &line)
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QStringList &DebugReader::fullOutput() const
|
||||||
|
{
|
||||||
|
return mFullOutput;
|
||||||
|
}
|
||||||
|
|
||||||
bool DebugReader::receivedSFWarning() const
|
bool DebugReader::receivedSFWarning() const
|
||||||
{
|
{
|
||||||
return mReceivedSFWarning;
|
return mReceivedSFWarning;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QStringList &DebugReader::memoryValue() const
|
|
||||||
{
|
|
||||||
return mMemoryValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebugReader::updateMemory() const
|
|
||||||
{
|
|
||||||
return mUpdateMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString &DebugReader::evalValue() const
|
|
||||||
{
|
|
||||||
return mEvalValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebugReader::evalReady() const
|
|
||||||
{
|
|
||||||
return mEvalReady;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QStringList &DebugReader::localsValue() const
|
|
||||||
{
|
|
||||||
return mLocalsValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebugReader::updateLocals() const
|
|
||||||
{
|
|
||||||
return mUpdateLocals;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebugReader::updateCPUInfo() const
|
bool DebugReader::updateCPUInfo() const
|
||||||
{
|
{
|
||||||
return mUpdateCPUInfo;
|
return mUpdateCPUInfo;
|
||||||
|
@ -1715,16 +1200,6 @@ const PDebugCommand &DebugReader::currentCmd() const
|
||||||
return mCurrentCmd;
|
return mCurrentCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &DebugReader::breakPointFile() const
|
|
||||||
{
|
|
||||||
return mBreakPointFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DebugReader::breakPointLine() const
|
|
||||||
{
|
|
||||||
return mBreakPointLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QStringList &DebugReader::consoleOutput() const
|
const QStringList &DebugReader::consoleOutput() const
|
||||||
{
|
{
|
||||||
return mConsoleOutput;
|
return mConsoleOutput;
|
||||||
|
@ -1735,21 +1210,11 @@ bool DebugReader::signalReceived() const
|
||||||
return mSignalReceived;
|
return mSignalReceived;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebugReader::updateExecution() const
|
|
||||||
{
|
|
||||||
return mUpdateExecution;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebugReader::processExited() const
|
bool DebugReader::processExited() const
|
||||||
{
|
{
|
||||||
return mProcessExited;
|
return mProcessExited;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebugReader::inferiorPaused() const
|
|
||||||
{
|
|
||||||
return mInferiorPaused;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebugReader::invalidateAllVars() const
|
bool DebugReader::invalidateAllVars() const
|
||||||
{
|
{
|
||||||
return mInvalidateAllVars;
|
return mInvalidateAllVars;
|
||||||
|
@ -1780,7 +1245,7 @@ bool DebugReader::commandRunning()
|
||||||
return !mCmdQueue.isEmpty();
|
return !mCmdQueue.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebugReader::waitStart()
|
void DebugReader::waitStart()
|
||||||
{
|
{
|
||||||
mStartSemaphore.acquire(1);
|
mStartSemaphore.acquire(1);
|
||||||
}
|
}
|
||||||
|
@ -1843,8 +1308,7 @@ void DebugReader::run()
|
||||||
readed = mProcess->readAll();
|
readed = mProcess->readAll();
|
||||||
buffer += readed;
|
buffer += readed;
|
||||||
|
|
||||||
|
if ( readed.endsWith("\n")&& outputTerminated(buffer)) {
|
||||||
if ( readed.endsWith("\r\n")&& outputTerminated(buffer)) {
|
|
||||||
processDebugOutput(buffer);
|
processDebugOutput(buffer);
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
mCmdRunning = false;
|
mCmdRunning = false;
|
||||||
|
|
|
@ -23,8 +23,6 @@ enum class DebugCommandSource {
|
||||||
struct DebugCommand{
|
struct DebugCommand{
|
||||||
QString command;
|
QString command;
|
||||||
QString params;
|
QString params;
|
||||||
bool updateWatch;
|
|
||||||
bool showInConsole;
|
|
||||||
DebugCommandSource source;
|
DebugCommandSource source;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,8 +174,6 @@ public:
|
||||||
// Play/pause
|
// Play/pause
|
||||||
bool start();
|
bool start();
|
||||||
void sendCommand(const QString& command, const QString& params,
|
void sendCommand(const QString& command, const QString& params,
|
||||||
bool updateWatch = true,
|
|
||||||
bool showInConsole = false,
|
|
||||||
DebugCommandSource source = DebugCommandSource::Other);
|
DebugCommandSource source = DebugCommandSource::Other);
|
||||||
bool commandRunning();
|
bool commandRunning();
|
||||||
|
|
||||||
|
@ -267,14 +263,14 @@ class DebugReader : public QThread
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit DebugReader(Debugger* debugger, QObject *parent = nullptr);
|
explicit DebugReader(Debugger* debugger, QObject *parent = nullptr);
|
||||||
void postCommand(const QString &Command, const QString &Params,
|
void postCommand(const QString &Command, const QString &Params, DebugCommandSource Source);
|
||||||
bool UpdateWatch, bool ShowInConsole, DebugCommandSource Source);
|
void registerInferiorStoppedCommand(const QString &Command, const QString &Params);
|
||||||
QString debuggerPath() const;
|
QString debuggerPath() const;
|
||||||
void setDebuggerPath(const QString &debuggerPath);
|
void setDebuggerPath(const QString &debuggerPath);
|
||||||
void stopDebug();
|
void stopDebug();
|
||||||
|
|
||||||
bool commandRunning();
|
bool commandRunning();
|
||||||
bool waitStart();
|
void waitStart();
|
||||||
|
|
||||||
bool invalidateAllVars() const;
|
bool invalidateAllVars() const;
|
||||||
void setInvalidateAllVars(bool invalidateAllVars);
|
void setInvalidateAllVars(bool invalidateAllVars);
|
||||||
|
@ -283,8 +279,6 @@ public:
|
||||||
|
|
||||||
bool processExited() const;
|
bool processExited() const;
|
||||||
|
|
||||||
bool updateExecution() const;
|
|
||||||
|
|
||||||
bool signalReceived() const;
|
bool signalReceived() const;
|
||||||
|
|
||||||
const QStringList &consoleOutput() const;
|
const QStringList &consoleOutput() const;
|
||||||
|
@ -311,13 +305,13 @@ public:
|
||||||
|
|
||||||
bool receivedSFWarning() const;
|
bool receivedSFWarning() const;
|
||||||
|
|
||||||
|
const QStringList &fullOutput() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void parseStarted();
|
void parseStarted();
|
||||||
void invalidateAllVars();
|
void invalidateAllVars();
|
||||||
void parseFinished();
|
void parseFinished();
|
||||||
void writeToDebugFailed();
|
void writeToDebugFailed();
|
||||||
void pauseWatchUpdate();
|
|
||||||
void updateWatch();
|
|
||||||
void processError(QProcess::ProcessError error);
|
void processError(QProcess::ProcessError error);
|
||||||
void changeDebugConsoleLastLine(const QString& text);
|
void changeDebugConsoleLastLine(const QString& text);
|
||||||
void cmdStarted();
|
void cmdStarted();
|
||||||
|
@ -325,32 +319,19 @@ signals:
|
||||||
|
|
||||||
void breakpointInfoGetted(const QString& filename, int line, int number);
|
void breakpointInfoGetted(const QString& filename, int line, int number);
|
||||||
void inferiorContinued();
|
void inferiorContinued();
|
||||||
void inferiorStopped(const QString& filename, int line);
|
void inferiorStopped(const QString& filename, int line, bool setFocus);
|
||||||
void localsUpdated(const QStringList& localsValue);
|
void localsUpdated(const QStringList& localsValue);
|
||||||
void evalUpdated(const QString& value);
|
void evalUpdated(const QString& value);
|
||||||
void memoryUpdated(const QStringList& memoryValues);
|
void memoryUpdated(const QStringList& memoryValues);
|
||||||
private:
|
private:
|
||||||
void clearCmdQueue();
|
void clearCmdQueue();
|
||||||
bool outputTerminated(QByteArray& text);
|
|
||||||
void handleDisassembly();
|
|
||||||
void handleDisplay();
|
|
||||||
void handleError();
|
|
||||||
void handleExit();
|
|
||||||
void handleLocalOutput();
|
|
||||||
void handleLocals();
|
|
||||||
void handleMemory();
|
|
||||||
void handleParams();
|
|
||||||
void handleRegisters();
|
|
||||||
void handleSignal();
|
|
||||||
void handleSource();
|
|
||||||
void handleValueHistoryValue();
|
|
||||||
|
|
||||||
|
|
||||||
QString processEvalOutput();
|
QString processEvalOutput();
|
||||||
void processWatchOutput(PWatchVar WatchVar);
|
void processWatchOutput(PWatchVar WatchVar);
|
||||||
void runNextCmd();
|
void runNextCmd();
|
||||||
QStringList tokenize(const QString& s);
|
QStringList tokenize(const QString& s);
|
||||||
|
|
||||||
|
bool outputTerminated(const QByteArray& text);
|
||||||
void handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint);
|
void handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint);
|
||||||
void handleStack(const QList<GDBMIResultParser::ParseValue> & stack);
|
void handleStack(const QList<GDBMIResultParser::ParseValue> & stack);
|
||||||
void handleLocalVariables(const QList<GDBMIResultParser::ParseValue> & variables);
|
void handleLocalVariables(const QList<GDBMIResultParser::ParseValue> & variables);
|
||||||
|
@ -362,6 +343,7 @@ private:
|
||||||
void processError(const QByteArray& errorLine);
|
void processError(const QByteArray& errorLine);
|
||||||
void processResultRecord(const QByteArray& line);
|
void processResultRecord(const QByteArray& line);
|
||||||
void processDebugOutput(const QByteArray& debugOutput);
|
void processDebugOutput(const QByteArray& debugOutput);
|
||||||
|
void runInferiorStoppedHook();
|
||||||
QByteArray removeToken(const QByteArray& line);
|
QByteArray removeToken(const QByteArray& line);
|
||||||
private:
|
private:
|
||||||
Debugger *mDebugger;
|
Debugger *mDebugger;
|
||||||
|
@ -369,7 +351,6 @@ private:
|
||||||
QRecursiveMutex mCmdQueueMutex;
|
QRecursiveMutex mCmdQueueMutex;
|
||||||
QSemaphore mStartSemaphore;
|
QSemaphore mStartSemaphore;
|
||||||
QQueue<PDebugCommand> mCmdQueue;
|
QQueue<PDebugCommand> mCmdQueue;
|
||||||
int mUpdateCount;
|
|
||||||
bool mInvalidateAllVars;
|
bool mInvalidateAllVars;
|
||||||
|
|
||||||
//fOnInvalidateAllVars: TInvalidateAllVarsEvent;
|
//fOnInvalidateAllVars: TInvalidateAllVarsEvent;
|
||||||
|
@ -396,19 +377,19 @@ private:
|
||||||
bool doupdatememoryview;
|
bool doupdatememoryview;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
QList<PDebugCommand> mInferiorStoppedHookCommands;
|
||||||
bool mInferiorRunning;
|
bool mInferiorRunning;
|
||||||
bool mProcessExited;
|
bool mProcessExited;
|
||||||
|
|
||||||
bool mUpdateExecution;
|
|
||||||
bool mSignalReceived;
|
bool mSignalReceived;
|
||||||
bool mUpdateCPUInfo;
|
bool mUpdateCPUInfo;
|
||||||
bool mReceivedSFWarning;
|
bool mReceivedSFWarning;
|
||||||
|
|
||||||
|
int mCurrentLine;
|
||||||
|
int mCurrentAddress;
|
||||||
|
QString mCurrentFile;
|
||||||
QStringList mConsoleOutput;
|
QStringList mConsoleOutput;
|
||||||
int mBreakPointLine;
|
QStringList mFullOutput;
|
||||||
QString mBreakPointFile;
|
|
||||||
|
|
||||||
|
|
||||||
bool mStop;
|
bool mStop;
|
||||||
// QThread interface
|
// QThread interface
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -2826,7 +2826,7 @@ void Editor::showDebugHint(const QString &s, int line)
|
||||||
connect(pMainWindow->debugger(), &Debugger::evalValueReady,
|
connect(pMainWindow->debugger(), &Debugger::evalValueReady,
|
||||||
this, &Editor::onTipEvalValueReady);
|
this, &Editor::onTipEvalValueReady);
|
||||||
mCurrentDebugTipWord = s;
|
mCurrentDebugTipWord = s;
|
||||||
pMainWindow->debugger()->sendCommand("print",s,false);
|
pMainWindow->debugger()->sendCommand("print",s);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Editor::getErrorHint(const PSyntaxIssue& issue)
|
QString Editor::getErrorHint(const PSyntaxIssue& issue)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
GDBMIResultParser::GDBMIResultParser()
|
GDBMIResultParser::GDBMIResultParser()
|
||||||
{
|
{
|
||||||
|
@ -38,17 +39,20 @@ bool GDBMIResultParser::parseAsyncResult(const QByteArray &record, QByteArray &r
|
||||||
if (*p!='*')
|
if (*p!='*')
|
||||||
return false;
|
return false;
|
||||||
p++;
|
p++;
|
||||||
const char* start;
|
const char* start=p;
|
||||||
while (*p && *p!=',')
|
while (*p && *p!=',')
|
||||||
p++;
|
p++;
|
||||||
result = QByteArray(start,p-start);
|
result = QByteArray(start,p-start);
|
||||||
if (*p==0)
|
if (*p==0)
|
||||||
return true;
|
return true;
|
||||||
|
p++;
|
||||||
return parseMultiValues(p,multiValue);
|
return parseMultiValues(p,multiValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GDBMIResultParser::parseMultiValues(const char* p, ParseObject &multiValue)
|
bool GDBMIResultParser::parseMultiValues(const char* p, ParseObject &multiValue)
|
||||||
{
|
{
|
||||||
|
qDebug()<<"-------";
|
||||||
|
qDebug()<<QByteArray(p);
|
||||||
while (*p) {
|
while (*p) {
|
||||||
QByteArray propName;
|
QByteArray propName;
|
||||||
ParseValue propValue;
|
ParseValue propValue;
|
||||||
|
@ -59,11 +63,12 @@ bool GDBMIResultParser::parseMultiValues(const char* p, ParseObject &multiValue)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
skipSpaces(p);
|
skipSpaces(p);
|
||||||
|
if (*p==0)
|
||||||
|
break;
|
||||||
if (*p!=',')
|
if (*p!=',')
|
||||||
return false;
|
return false;
|
||||||
p++; //skip ','
|
p++; //skip ','
|
||||||
skipSpaces(p);
|
skipSpaces(p);
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -81,6 +86,7 @@ bool GDBMIResultParser::parseNameAndValue(const char *&p, QByteArray &name, Pars
|
||||||
skipSpaces(p);
|
skipSpaces(p);
|
||||||
if (*p!='=')
|
if (*p!='=')
|
||||||
return false;
|
return false;
|
||||||
|
p++;
|
||||||
return parseValue(p,value);
|
return parseValue(p,value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +102,7 @@ bool GDBMIResultParser::parseValue(const char *&p, ParseValue &value)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '[': {
|
case '[': {
|
||||||
QList<ParseObject> array;
|
QList<ParseValue> array;
|
||||||
result = parseArray(p,array);
|
result = parseArray(p,array);
|
||||||
value = array;
|
value = array;
|
||||||
break;
|
break;
|
||||||
|
@ -113,8 +119,6 @@ bool GDBMIResultParser::parseValue(const char *&p, ParseValue &value)
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
skipSpaces(p);
|
skipSpaces(p);
|
||||||
if (*p!=0 && *p!=',')
|
|
||||||
return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,18 +127,85 @@ bool GDBMIResultParser::parseStringValue(const char *&p, QByteArray& stringValue
|
||||||
if (*p!='"')
|
if (*p!='"')
|
||||||
return false;
|
return false;
|
||||||
p++;
|
p++;
|
||||||
const char* valueStart = p;
|
stringValue.clear();
|
||||||
while (*p!=0) {
|
while (*p!=0) {
|
||||||
if (*p == '"') {
|
if (*p == '"') {
|
||||||
break;
|
break;
|
||||||
} else if (*p=='\\' && *(p+1)!=0) {
|
} else if (*p=='\\' && *(p+1)!=0) {
|
||||||
p+=2;
|
p++;
|
||||||
|
switch (*p) {
|
||||||
|
case '\'':
|
||||||
|
stringValue+=0x27;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
stringValue+=0x22;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
stringValue+=0x3f;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
stringValue+=0x5c;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
stringValue+=0x07;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
stringValue+=0x08;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
stringValue+=0x0c;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
stringValue+=0x0a;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
stringValue+=0x0d;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
stringValue+=0x09;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
stringValue+=0x0b;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
for (i=0;i<3;i++) {
|
||||||
|
if (*(p+i)<'0' || *(p+i)>'7')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QByteArray numStr(p,i);
|
||||||
|
bool ok;
|
||||||
|
unsigned char ch = numStr.toInt(&ok,8);
|
||||||
|
stringValue+=ch;
|
||||||
|
p+=i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
stringValue+=*p;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*p=='"') {
|
if (*p=='"') {
|
||||||
stringValue = QByteArray(valueStart,p-valueStart);
|
|
||||||
p++; //skip '"'
|
p++; //skip '"'
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -152,6 +223,7 @@ bool GDBMIResultParser::parseObject(const char *&p, ParseObject &obj)
|
||||||
QByteArray propName;
|
QByteArray propName;
|
||||||
ParseValue propValue;
|
ParseValue propValue;
|
||||||
bool result = parseNameAndValue(p,propName,propValue);
|
bool result = parseNameAndValue(p,propName,propValue);
|
||||||
|
qDebug()<<result<<propName<<QByteArray(p);
|
||||||
if (result) {
|
if (result) {
|
||||||
obj[propName]=propValue;
|
obj[propName]=propValue;
|
||||||
} else {
|
} else {
|
||||||
|
@ -160,8 +232,9 @@ bool GDBMIResultParser::parseObject(const char *&p, ParseObject &obj)
|
||||||
skipSpaces(p);
|
skipSpaces(p);
|
||||||
if (*p=='}')
|
if (*p=='}')
|
||||||
break;
|
break;
|
||||||
if (*p!=',')
|
if (*p!=',') {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
p++; //skip ','
|
p++; //skip ','
|
||||||
skipSpaces(p);
|
skipSpaces(p);
|
||||||
}
|
}
|
||||||
|
@ -260,6 +333,17 @@ int GDBMIResultParser::ParseValue::intValue(int defaultValue) const
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GDBMIResultParser::ParseValue::hexValue(int defaultValue) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(mType == ParseValueType::Value);
|
||||||
|
bool ok;
|
||||||
|
int value = QString(mValue).toInt(&ok,16);
|
||||||
|
if (ok)
|
||||||
|
return value;
|
||||||
|
else
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
QString GDBMIResultParser::ParseValue::pathValue() const
|
QString GDBMIResultParser::ParseValue::pathValue() const
|
||||||
{
|
{
|
||||||
Q_ASSERT(mType == ParseValueType::Value);
|
Q_ASSERT(mType == ParseValueType::Value);
|
||||||
|
@ -271,6 +355,11 @@ GDBMIResultParser::ParseValueType GDBMIResultParser::ParseValue::type() const
|
||||||
return mType;
|
return mType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GDBMIResultParser::ParseValue::isValid() const
|
||||||
|
{
|
||||||
|
return mType!=ParseValueType::NotAssigned;
|
||||||
|
}
|
||||||
|
|
||||||
GDBMIResultParser::ParseValue::ParseValue():
|
GDBMIResultParser::ParseValue::ParseValue():
|
||||||
mType(ParseValueType::NotAssigned) {
|
mType(ParseValueType::NotAssigned) {
|
||||||
|
|
||||||
|
@ -294,11 +383,29 @@ GDBMIResultParser::ParseValue::ParseValue(const QList<ParseValue> &array):
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GDBMIResultParser::ParseValue::ParseValue(const ParseValue &value):
|
||||||
|
mValue(value.mValue),
|
||||||
|
mArray(value.mArray),
|
||||||
|
mObject(value.mObject),
|
||||||
|
mType(value.mType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const GDBMIResultParser::ParseValue &value)
|
||||||
|
{
|
||||||
|
mType = value.mType;
|
||||||
|
mValue = value.mValue;
|
||||||
|
mArray = value.mArray;
|
||||||
|
mObject = value.mObject;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const QByteArray &value)
|
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const QByteArray &value)
|
||||||
{
|
{
|
||||||
Q_ASSERT(mType == ParseValueType::NotAssigned);
|
Q_ASSERT(mType == ParseValueType::NotAssigned);
|
||||||
mType = ParseValueType::Value;
|
mType = ParseValueType::Value;
|
||||||
mValue = value;
|
mValue = value;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const ParseObject& object)
|
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const ParseObject& object)
|
||||||
|
@ -306,6 +413,7 @@ GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const Pa
|
||||||
Q_ASSERT(mType == ParseValueType::NotAssigned);
|
Q_ASSERT(mType == ParseValueType::NotAssigned);
|
||||||
mType = ParseValueType::Object;
|
mType = ParseValueType::Object;
|
||||||
mObject = object;
|
mObject = object;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const QList<ParseValue>& array)
|
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const QList<ParseValue>& array)
|
||||||
|
@ -313,19 +421,34 @@ GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const QL
|
||||||
Q_ASSERT(mType == ParseValueType::NotAssigned);
|
Q_ASSERT(mType == ParseValueType::NotAssigned);
|
||||||
mType = ParseValueType::Array;
|
mType = ParseValueType::Array;
|
||||||
mArray = array;
|
mArray = array;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const GDBMIResultParser::ParseValue GDBMIResultParser::ParseObject::operator[](const QByteArray &name) const
|
GDBMIResultParser::ParseObject::ParseObject()
|
||||||
{
|
{
|
||||||
if (mProps.contains(name))
|
|
||||||
return mProps[name];
|
}
|
||||||
|
|
||||||
|
GDBMIResultParser::ParseObject::ParseObject(const ParseObject &object):
|
||||||
|
mProps(object.mProps)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GDBMIResultParser::ParseValue GDBMIResultParser::ParseObject::operator[](const QByteArray &name) const
|
||||||
|
{
|
||||||
|
if (mProps.contains(name)) {
|
||||||
|
ParseValue value(mProps[name]);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
return ParseValue();
|
return ParseValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
GDBMIResultParser::ParseObject &GDBMIResultParser::ParseObject::operator=(const ParseObject &object)
|
GDBMIResultParser::ParseObject &GDBMIResultParser::ParseObject::operator=(const ParseObject &object)
|
||||||
{
|
{
|
||||||
mProps = object.mProps;
|
mProps = object.mProps;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseObject::operator[](const QByteArray &name) {
|
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseObject::operator[](const QByteArray &name) {
|
||||||
|
|
|
@ -36,7 +36,9 @@ public:
|
||||||
|
|
||||||
class ParseObject {
|
class ParseObject {
|
||||||
public:
|
public:
|
||||||
const ParseValue operator[](const QByteArray& name) const;
|
explicit ParseObject();
|
||||||
|
ParseObject(const ParseObject& object);
|
||||||
|
ParseValue operator[](const QByteArray& name) const;
|
||||||
ParseValue& operator[](const QByteArray& name);
|
ParseValue& operator[](const QByteArray& name);
|
||||||
ParseObject& operator=(const ParseObject& object);
|
ParseObject& operator=(const ParseObject& object);
|
||||||
private:
|
private:
|
||||||
|
@ -49,13 +51,16 @@ public:
|
||||||
explicit ParseValue(const QByteArray& value);
|
explicit ParseValue(const QByteArray& value);
|
||||||
explicit ParseValue(const ParseObject &object);
|
explicit ParseValue(const ParseObject &object);
|
||||||
explicit ParseValue(const QList<ParseValue>& array);
|
explicit ParseValue(const QList<ParseValue>& array);
|
||||||
ParseValue(const ParseValue&) = delete;
|
ParseValue(const ParseValue& value);
|
||||||
const QByteArray &value() const;
|
const QByteArray &value() const;
|
||||||
const QList<ParseValue> &array() const;
|
const QList<ParseValue> &array() const;
|
||||||
const ParseObject &object() const;
|
const ParseObject &object() const;
|
||||||
int intValue(int defaultValue=-1) const;
|
int intValue(int defaultValue=-1) const;
|
||||||
|
int hexValue(int defaultValue=-1) const;
|
||||||
|
|
||||||
QString pathValue() const;
|
QString pathValue() const;
|
||||||
ParseValueType type() const;
|
ParseValueType type() const;
|
||||||
|
bool isValid() const;
|
||||||
ParseValue& operator=(const QByteArray& value);
|
ParseValue& operator=(const QByteArray& value);
|
||||||
ParseValue& operator=(const ParseObject& object);
|
ParseValue& operator=(const ParseObject& object);
|
||||||
ParseValue& operator=(const QList<ParseValue>& array);
|
ParseValue& operator=(const QList<ParseValue>& array);
|
||||||
|
|
|
@ -1444,11 +1444,9 @@ void MainWindow::debug()
|
||||||
return;
|
return;
|
||||||
case CompileTarget::File:
|
case CompileTarget::File:
|
||||||
mDebugger->sendCommand("-exec-run", "--start");
|
mDebugger->sendCommand("-exec-run", "--start");
|
||||||
mDebugger->updateDebugInfo();
|
|
||||||
break;
|
break;
|
||||||
case CompileTarget::Project:
|
case CompileTarget::Project:
|
||||||
mDebugger->sendCommand("-exec-run", "--start");
|
mDebugger->sendCommand("-exec-run", "--start");
|
||||||
mDebugger->updateDebugInfo();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1459,11 +1457,9 @@ void MainWindow::debug()
|
||||||
return;
|
return;
|
||||||
case CompileTarget::File:
|
case CompileTarget::File:
|
||||||
mDebugger->sendCommand("-exec-run","");
|
mDebugger->sendCommand("-exec-run","");
|
||||||
mDebugger->updateDebugInfo();
|
|
||||||
break;
|
break;
|
||||||
case CompileTarget::Project:
|
case CompileTarget::Project:
|
||||||
mDebugger->sendCommand("-exec-run","");
|
mDebugger->sendCommand("-exec-run","");
|
||||||
mDebugger->updateDebugInfo();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -3698,7 +3694,7 @@ void MainWindow::cleanUpCPUDialog()
|
||||||
void MainWindow::onDebugCommandInput(const QString& command)
|
void MainWindow::onDebugCommandInput(const QString& command)
|
||||||
{
|
{
|
||||||
if (mDebugger->executing()) {
|
if (mDebugger->executing()) {
|
||||||
mDebugger->sendCommand(command,"",true,true);
|
mDebugger->sendCommand(command,"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3978,8 +3974,6 @@ void MainWindow::on_actionStep_Over_triggered()
|
||||||
//WatchView.Items.BeginUpdate();
|
//WatchView.Items.BeginUpdate();
|
||||||
mDebugger->invalidateAllVars();
|
mDebugger->invalidateAllVars();
|
||||||
mDebugger->sendCommand("-exec-next", "");
|
mDebugger->sendCommand("-exec-next", "");
|
||||||
mDebugger->updateDebugInfo();
|
|
||||||
mDebugger->refreshWatchVars();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3989,8 +3983,6 @@ void MainWindow::on_actionStep_Into_triggered()
|
||||||
//WatchView.Items.BeginUpdate();
|
//WatchView.Items.BeginUpdate();
|
||||||
mDebugger->invalidateAllVars();
|
mDebugger->invalidateAllVars();
|
||||||
mDebugger->sendCommand("-exec-step", "");
|
mDebugger->sendCommand("-exec-step", "");
|
||||||
mDebugger->updateDebugInfo();
|
|
||||||
mDebugger->refreshWatchVars();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4001,8 +3993,6 @@ void MainWindow::on_actionStep_Out_triggered()
|
||||||
//WatchView.Items.BeginUpdate();
|
//WatchView.Items.BeginUpdate();
|
||||||
mDebugger->invalidateAllVars();
|
mDebugger->invalidateAllVars();
|
||||||
mDebugger->sendCommand("-exec-finish", "");
|
mDebugger->sendCommand("-exec-finish", "");
|
||||||
mDebugger->updateDebugInfo();
|
|
||||||
mDebugger->refreshWatchVars();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4014,10 +4004,9 @@ void MainWindow::on_actionRun_To_Cursor_triggered()
|
||||||
if (e!=nullptr) {
|
if (e!=nullptr) {
|
||||||
//WatchView.Items.BeginUpdate();
|
//WatchView.Items.BeginUpdate();
|
||||||
mDebugger->invalidateAllVars();
|
mDebugger->invalidateAllVars();
|
||||||
mDebugger->sendCommand("-break-insert", QString("-t --line %1").arg(e->caretY()));
|
mDebugger->sendCommand("-exec-until", QString("\"%1\":%2")
|
||||||
mDebugger->sendCommand("-exec-continue", "");
|
.arg(e->filename())
|
||||||
mDebugger->updateDebugInfo();
|
.arg(e->caretY()));
|
||||||
mDebugger->refreshWatchVars();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4079,7 +4068,7 @@ void MainWindow::onDebugEvaluateInput()
|
||||||
if (!s.isEmpty()) {
|
if (!s.isEmpty()) {
|
||||||
connect(mDebugger, &Debugger::evalValueReady,
|
connect(mDebugger, &Debugger::evalValueReady,
|
||||||
this, &MainWindow::onEvalValueReady);
|
this, &MainWindow::onEvalValueReady);
|
||||||
mDebugger->sendCommand("print",s,false);
|
mDebugger->sendCommand("print",s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4089,7 +4078,7 @@ void MainWindow::onDebugMemoryAddressInput()
|
||||||
if (!s.isEmpty()) {
|
if (!s.isEmpty()) {
|
||||||
connect(mDebugger, &Debugger::memoryExamineReady,
|
connect(mDebugger, &Debugger::memoryExamineReady,
|
||||||
this, &MainWindow::onMemoryExamineReady);
|
this, &MainWindow::onMemoryExamineReady);
|
||||||
mDebugger->sendCommand("-data-read-memory/64bx",s,false);
|
mDebugger->sendCommand("-data-read-memory/64bx",s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,6 @@ public:
|
||||||
QFileSystemWatcher* fileSystemWatcher();
|
QFileSystemWatcher* fileSystemWatcher();
|
||||||
|
|
||||||
void removeActiveBreakpoints();
|
void removeActiveBreakpoints();
|
||||||
void setActiveBreakpoint(QString FileName, int Line, bool setFocus=true);
|
|
||||||
void updateAppTitle();
|
void updateAppTitle();
|
||||||
void addDebugOutput(const QString& text);
|
void addDebugOutput(const QString& text);
|
||||||
void changeDebugOutputLastline(const QString& text);
|
void changeDebugOutputLastline(const QString& text);
|
||||||
|
@ -193,6 +192,7 @@ public slots:
|
||||||
void onTodoParseStarted(const QString& filename);
|
void onTodoParseStarted(const QString& filename);
|
||||||
void onTodoParsing(const QString& filename, int lineNo, int ch, const QString& line);
|
void onTodoParsing(const QString& filename, int lineNo, int ch, const QString& line);
|
||||||
void onTodoParseFinished();
|
void onTodoParseFinished();
|
||||||
|
void setActiveBreakpoint(QString FileName, int Line, bool setFocus);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void prepareProjectForCompile();
|
void prepareProjectForCompile();
|
||||||
|
|
|
@ -1819,7 +1819,7 @@ void SynEdit::doDeleteLastChar()
|
||||||
mLines->deleteAt(mCaretY);
|
mLines->deleteAt(mCaretY);
|
||||||
doLinesDeleted(mCaretY+1, 1);
|
doLinesDeleted(mCaretY+1, 1);
|
||||||
if (mOptions.testFlag(eoTrimTrailingSpaces))
|
if (mOptions.testFlag(eoTrimTrailingSpaces))
|
||||||
Temp = TrimRight(Temp);
|
Temp = trimRight(Temp);
|
||||||
setLineText(lineText() + Temp);
|
setLineText(lineText() + Temp);
|
||||||
helper = lineBreak(); //"/r/n"
|
helper = lineBreak(); //"/r/n"
|
||||||
}
|
}
|
||||||
|
@ -2153,7 +2153,7 @@ void SynEdit::insertLine(bool moveCaret)
|
||||||
rightLineText,mOptions.testFlag(eoAutoIndent)
|
rightLineText,mOptions.testFlag(eoAutoIndent)
|
||||||
&& notInComment);
|
&& notInComment);
|
||||||
if (mOptions.testFlag(eoAutoIndent)) {
|
if (mOptions.testFlag(eoAutoIndent)) {
|
||||||
rightLineText=TrimLeft(rightLineText);
|
rightLineText=trimLeft(rightLineText);
|
||||||
}
|
}
|
||||||
QString indentSpacesForRightLineText = GetLeftSpacing(indentSpaces,true);
|
QString indentSpacesForRightLineText = GetLeftSpacing(indentSpaces,true);
|
||||||
mLines->insert(mCaretY, indentSpacesForRightLineText+rightLineText);
|
mLines->insert(mCaretY, indentSpacesForRightLineText+rightLineText);
|
||||||
|
@ -2670,7 +2670,7 @@ void SynEdit::doAddChar(QChar AChar)
|
||||||
if (line.length() < oldCaretX) {
|
if (line.length() < oldCaretX) {
|
||||||
int indentSpaces = calcIndentSpaces(oldCaretY,line+":", true);
|
int indentSpaces = calcIndentSpaces(oldCaretY,line+":", true);
|
||||||
if (indentSpaces != leftSpaces(line)) {
|
if (indentSpaces != leftSpaces(line)) {
|
||||||
QString newLine = GetLeftSpacing(indentSpaces,true) + TrimLeft(line);
|
QString newLine = GetLeftSpacing(indentSpaces,true) + trimLeft(line);
|
||||||
int i = newLine.length();
|
int i = newLine.length();
|
||||||
mLines->putString(oldCaretY-1,newLine);
|
mLines->putString(oldCaretY-1,newLine);
|
||||||
internalSetCaretXY(BufferCoord{i+1,oldCaretY});
|
internalSetCaretXY(BufferCoord{i+1,oldCaretY});
|
||||||
|
@ -4965,7 +4965,7 @@ void SynEdit::doLinesInserted(int firstLine, int count)
|
||||||
void SynEdit::properSetLine(int ALine, const QString &ALineText, bool notify)
|
void SynEdit::properSetLine(int ALine, const QString &ALineText, bool notify)
|
||||||
{
|
{
|
||||||
if (mOptions.testFlag(eoTrimTrailingSpaces)) {
|
if (mOptions.testFlag(eoTrimTrailingSpaces)) {
|
||||||
mLines->putString(ALine,TrimRight(ALineText),notify);
|
mLines->putString(ALine,trimRight(ALineText),notify);
|
||||||
} else {
|
} else {
|
||||||
mLines->putString(ALine,ALineText,notify);
|
mLines->putString(ALine,ALineText,notify);
|
||||||
}
|
}
|
||||||
|
@ -5077,7 +5077,7 @@ int SynEdit::insertTextByNormalMode(const QString &Value)
|
||||||
int startLine = mCaretY;
|
int startLine = mCaretY;
|
||||||
sLeftSide = lineText().mid(0, mCaretX - 1);
|
sLeftSide = lineText().mid(0, mCaretX - 1);
|
||||||
if (mCaretX - 1 > sLeftSide.length()) {
|
if (mCaretX - 1 > sLeftSide.length()) {
|
||||||
if (StringIsBlank(sLeftSide))
|
if (stringIsBlank(sLeftSide))
|
||||||
sLeftSide = GetLeftSpacing(displayX() - 1, true);
|
sLeftSide = GetLeftSpacing(displayX() - 1, true);
|
||||||
else
|
else
|
||||||
sLeftSide += QString(mCaretX - 1 - sLeftSide.length(),' ');
|
sLeftSide += QString(mCaretX - 1 - sLeftSide.length(),' ');
|
||||||
|
@ -5093,7 +5093,7 @@ int SynEdit::insertTextByNormalMode(const QString &Value)
|
||||||
Start = 0;
|
Start = 0;
|
||||||
P = GetEOL(Value,Start);
|
P = GetEOL(Value,Start);
|
||||||
if (P<Value.length()) {
|
if (P<Value.length()) {
|
||||||
QString s = TrimLeft(Value.mid(0, P - Start));
|
QString s = trimLeft(Value.mid(0, P - Start));
|
||||||
if (sLeftSide.isEmpty()) {
|
if (sLeftSide.isEmpty()) {
|
||||||
sLeftSide = GetLeftSpacing(calcIndentSpaces(caretY,s,true),true);
|
sLeftSide = GetLeftSpacing(calcIndentSpaces(caretY,s,true),true);
|
||||||
}
|
}
|
||||||
|
@ -5126,7 +5126,7 @@ int SynEdit::insertTextByNormalMode(const QString &Value)
|
||||||
Str += sRightSide;
|
Str += sRightSide;
|
||||||
if (mOptions.testFlag(eoAutoIndent)) {
|
if (mOptions.testFlag(eoAutoIndent)) {
|
||||||
int indentSpaces = calcIndentSpaces(caretY,Str,true);
|
int indentSpaces = calcIndentSpaces(caretY,Str,true);
|
||||||
Str = GetLeftSpacing(indentSpaces,true)+TrimLeft(Str);
|
Str = GetLeftSpacing(indentSpaces,true)+trimLeft(Str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
properSetLine(caretY - 1, Str,false);
|
properSetLine(caretY - 1, Str,false);
|
||||||
|
|
Loading…
Reference in New Issue