work save

This commit is contained in:
Roy Qu 2021-11-24 17:53:25 +08:00
parent fdfa7c779f
commit b17406eb07
8 changed files with 296 additions and 734 deletions

View File

@ -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 &params, bool updateWatch, bool showInConsole, DebugCommandSource source) void Debugger::sendCommand(const QString &command, const QString &params, 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;
}
} }
for (const QString& line:outStrList) { } else {
for (const QString& line:mReader->consoleOutput()) {
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) { // if (mReader->dodisassemblerready) {
pMainWindow->cpuDialog()->setDisassembly(mReader->mDisassembly); // pMainWindow->cpuDialog()->setDisassembly(mReader->mDisassembly);
mReader->mDisassembly.clear(); // mReader->mDisassembly.clear();
mReader->dodisassemblerready = false; // mReader->dodisassemblerready = false;
} // }
} }
if (mReader->updateExecution()) { // if (mReader->updateExecution()) {
if (mReader->currentCmd() && mReader->currentCmd()->source == DebugCommandSource::Console) { // if (mReader->currentCmd() && mReader->currentCmd()->source == DebugCommandSource::Console) {
pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine(),false); // pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine(),false);
} else { // } else {
pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine()); // pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine());
} // }
refreshWatchVars(); // update variable information // 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,34 +968,19 @@ 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;
s=pCmd->command.toLocal8Bit(); s=pCmd->command.toLocal8Bit();
@ -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;

View File

@ -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:

View File

@ -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)

View File

@ -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) {

View File

@ -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);

View File

@ -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);
} }
} }

View File

@ -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();

View File

@ -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);