From efb43ac7f995767bf61c58c8712d6b3a0f436d13 Mon Sep 17 00:00:00 2001 From: chaoticgd <43898262+chaoticgd@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:56:19 +0000 Subject: [PATCH] Debugger: Make the expression parser thread safe --- pcsx2-qt/Debugger/BreakpointDialog.cpp | 22 ++++--- pcsx2-qt/Debugger/DisassemblyWidget.cpp | 5 +- pcsx2-qt/Debugger/MemoryViewWidget.cpp | 5 +- pcsx2-qt/Debugger/Models/BreakpointModel.cpp | 67 ++++++++++++-------- pcsx2/DebugTools/Breakpoints.h | 3 +- pcsx2/DebugTools/DebugInterface.cpp | 18 +++--- pcsx2/DebugTools/DebugInterface.h | 6 +- pcsx2/DebugTools/ExpressionParser.cpp | 52 ++++++--------- pcsx2/DebugTools/ExpressionParser.h | 7 +- pcsx2/DebugTools/MipsAssembler.cpp | 5 +- 10 files changed, 97 insertions(+), 93 deletions(-) diff --git a/pcsx2-qt/Debugger/BreakpointDialog.cpp b/pcsx2-qt/Debugger/BreakpointDialog.cpp index 1d5c511094..b38b9f38a0 100644 --- a/pcsx2-qt/Debugger/BreakpointDialog.cpp +++ b/pcsx2-qt/Debugger/BreakpointDialog.cpp @@ -80,6 +80,8 @@ void BreakpointDialog::onRdoButtonToggled() void BreakpointDialog::accept() { + std::string error; + if (m_purpose == PURPOSE::CREATE) { if (m_ui.rdoExecute->isChecked()) @@ -93,9 +95,9 @@ void BreakpointDialog::accept() PostfixExpression expr; u64 address; - if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), address)) + if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), address, error)) { - QMessageBox::warning(this, tr("Invalid Address"), getExpressionError()); + QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error)); return; } @@ -108,9 +110,9 @@ void BreakpointDialog::accept() bp->hasCond = true; bp->cond.debug = m_cpu; - if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr)) + if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error)) { - QMessageBox::warning(this, tr("Invalid Condition"), getExpressionError()); + QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error)); return; } @@ -121,16 +123,16 @@ void BreakpointDialog::accept() if (auto* mc = std::get_if(&m_bp_mc)) { u64 startAddress; - if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), startAddress)) + if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), startAddress, error)) { - QMessageBox::warning(this, tr("Invalid Address"), getExpressionError()); + QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error)); return; } u64 size; - if (!m_cpu->evaluateExpression(m_ui.txtSize->text().toStdString().c_str(), size) || !size) + if (!m_cpu->evaluateExpression(m_ui.txtSize->text().toStdString().c_str(), size, error) || !size) { - QMessageBox::warning(this, tr("Invalid Size"), getExpressionError()); + QMessageBox::warning(this, tr("Invalid Size"), QString::fromStdString(error)); return; } @@ -143,9 +145,9 @@ void BreakpointDialog::accept() mc->cond.debug = m_cpu; PostfixExpression expr; - if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr)) + if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error)) { - QMessageBox::warning(this, tr("Invalid Condition"), getExpressionError()); + QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error)); return; } diff --git a/pcsx2-qt/Debugger/DisassemblyWidget.cpp b/pcsx2-qt/Debugger/DisassemblyWidget.cpp index 4f75ad08a0..887b8185ff 100644 --- a/pcsx2-qt/Debugger/DisassemblyWidget.cpp +++ b/pcsx2-qt/Debugger/DisassemblyWidget.cpp @@ -170,9 +170,10 @@ void DisassemblyWidget::contextGoToAddress() return; u64 address = 0; - if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address)) + std::string error; + if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address, error)) { - QMessageBox::warning(this, tr("Cannot Go To"), getExpressionError()); + QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error)); return; } diff --git a/pcsx2-qt/Debugger/MemoryViewWidget.cpp b/pcsx2-qt/Debugger/MemoryViewWidget.cpp index f635dbc632..5fa56ff741 100644 --- a/pcsx2-qt/Debugger/MemoryViewWidget.cpp +++ b/pcsx2-qt/Debugger/MemoryViewWidget.cpp @@ -599,9 +599,10 @@ void MemoryViewWidget::contextGoToAddress() return; u64 address = 0; - if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address)) + std::string error; + if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address, error)) { - QMessageBox::warning(this, tr("Cannot Go To"), getExpressionError()); + QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error)); return; } diff --git a/pcsx2-qt/Debugger/Models/BreakpointModel.cpp b/pcsx2-qt/Debugger/Models/BreakpointModel.cpp index 07bb9bb898..fc4daa293a 100644 --- a/pcsx2-qt/Debugger/Models/BreakpointModel.cpp +++ b/pcsx2-qt/Debugger/Models/BreakpointModel.cpp @@ -273,6 +273,8 @@ Qt::ItemFlags BreakpointModel::flags(const QModelIndex& index) const bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, int role) { + std::string error; + if (role == Qt::CheckStateRole && index.column() == BreakpointColumns::ENABLED) { auto bp_mc = m_breakpoints.at(index.row()); @@ -314,9 +316,9 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i { PostfixExpression expr; - if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr)) + if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error)) { - QMessageBox::warning(nullptr, "Condition Error", QString(getExpressionError())); + QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error)); return false; } @@ -347,9 +349,9 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i { PostfixExpression expr; - if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr)) + if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error)) { - QMessageBox::warning(nullptr, "Condition Error", QString(getExpressionError())); + QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error)); return false; } @@ -456,17 +458,20 @@ void BreakpointModel::refreshData() void BreakpointModel::loadBreakpointFromFieldList(QStringList fields) { + std::string error; + bool ok; - if (fields.size() != BreakpointModel::BreakpointColumns::COLUMN_COUNT) + if (fields.size() != BreakpointColumns::COLUMN_COUNT) { Console.WriteLn("Debugger Breakpoint Model: Invalid number of columns, skipping"); return; } - const int type = fields[BreakpointModel::BreakpointColumns::TYPE].toUInt(&ok); + const int type = fields[BreakpointColumns::TYPE].toUInt(&ok); if (!ok) { - Console.WriteLn("Debugger Breakpoint Model: Failed to parse type '%s', skipping", fields[BreakpointModel::BreakpointColumns::TYPE].toUtf8().constData()); + Console.WriteLn("Debugger Breakpoint Model: Failed to parse type '%s', skipping", + fields[BreakpointColumns::TYPE].toUtf8().constData()); return; } @@ -476,34 +481,37 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields) BreakPoint bp; // Address - bp.addr = fields[BreakpointModel::BreakpointColumns::OFFSET].toUInt(&ok, 16); + bp.addr = fields[BreakpointColumns::OFFSET].toUInt(&ok, 16); if (!ok) { - Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", fields[BreakpointModel::BreakpointColumns::OFFSET].toUtf8().constData()); + Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", + fields[BreakpointColumns::OFFSET].toUtf8().constData()); return; } // Condition - if (!fields[BreakpointModel::BreakpointColumns::CONDITION].isEmpty()) + if (!fields[BreakpointColumns::CONDITION].isEmpty()) { PostfixExpression expr; bp.hasCond = true; bp.cond.debug = &m_cpu; - if (!m_cpu.initExpression(fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData(), expr)) + if (!m_cpu.initExpression(fields[BreakpointColumns::CONDITION].toUtf8().constData(), expr, error)) { - Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData()); + Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", + fields[BreakpointModel::CONDITION].toUtf8().constData()); return; } bp.cond.expression = expr; - bp.cond.expressionString = fields[BreakpointModel::BreakpointColumns::CONDITION].toStdString(); + bp.cond.expressionString = fields[BreakpointColumns::CONDITION].toStdString(); } // Enabled - bp.enabled = fields[BreakpointModel::BreakpointColumns::ENABLED].toUInt(&ok); + bp.enabled = fields[BreakpointColumns::ENABLED].toUInt(&ok); if (!ok) { - Console.WriteLn("Debugger Breakpoint Model: Failed to parse enable flag '%s', skipping", fields[BreakpointModel::BreakpointColumns::ENABLED].toUtf8().constData()); + Console.WriteLn("Debugger Breakpoint Model: Failed to parse enable flag '%s', skipping", + fields[BreakpointColumns::ENABLED].toUtf8().constData()); return; } @@ -515,49 +523,54 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields) // Mode if (type >= MEMCHECK_INVALID) { - Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond type '%s', skipping", fields[BreakpointModel::BreakpointColumns::TYPE].toUtf8().constData()); + Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond type '%s', skipping", + fields[BreakpointColumns::TYPE].toUtf8().constData()); return; } mc.memCond = static_cast(type); // Address - QString test = fields[BreakpointModel::BreakpointColumns::OFFSET]; - mc.start = fields[BreakpointModel::BreakpointColumns::OFFSET].toUInt(&ok, 16); + QString test = fields[BreakpointColumns::OFFSET]; + mc.start = fields[BreakpointColumns::OFFSET].toUInt(&ok, 16); if (!ok) { - Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", fields[BreakpointModel::BreakpointColumns::OFFSET].toUtf8().constData()); + Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", + fields[BreakpointColumns::OFFSET].toUtf8().constData()); return; } // Size - mc.end = fields[BreakpointModel::BreakpointColumns::SIZE_LABEL].toUInt(&ok) + mc.start; + mc.end = fields[BreakpointColumns::SIZE_LABEL].toUInt(&ok) + mc.start; if (!ok) { - Console.WriteLn("Debugger Breakpoint Model: Failed to parse length '%s', skipping", fields[BreakpointModel::BreakpointColumns::SIZE_LABEL].toUtf8().constData()); + Console.WriteLn("Debugger Breakpoint Model: Failed to parse length '%s', skipping", + fields[BreakpointColumns::SIZE_LABEL].toUtf8().constData()); return; } // Condition - if (!fields[BreakpointModel::BreakpointColumns::CONDITION].isEmpty()) + if (!fields[BreakpointColumns::CONDITION].isEmpty()) { PostfixExpression expr; mc.hasCond = true; mc.cond.debug = &m_cpu; - if (!m_cpu.initExpression(fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData(), expr)) + if (!m_cpu.initExpression(fields[BreakpointColumns::CONDITION].toUtf8().constData(), expr, error)) { - Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData()); + Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", + fields[BreakpointColumns::CONDITION].toUtf8().constData()); return; } mc.cond.expression = expr; - mc.cond.expressionString = fields[BreakpointModel::BreakpointColumns::CONDITION].toStdString(); + mc.cond.expressionString = fields[BreakpointColumns::CONDITION].toStdString(); } // Result - const int result = fields[BreakpointModel::BreakpointColumns::ENABLED].toUInt(&ok); + const int result = fields[BreakpointColumns::ENABLED].toUInt(&ok); if (!ok) { - Console.WriteLn("Debugger Breakpoint Model: Failed to parse result flag '%s', skipping", fields[BreakpointModel::BreakpointColumns::ENABLED].toUtf8().constData()); + Console.WriteLn("Debugger Breakpoint Model: Failed to parse result flag '%s', skipping", + fields[BreakpointColumns::ENABLED].toUtf8().constData()); return; } mc.result = static_cast(result); diff --git a/pcsx2/DebugTools/Breakpoints.h b/pcsx2/DebugTools/Breakpoints.h index 361c284f45..58942df012 100644 --- a/pcsx2/DebugTools/Breakpoints.h +++ b/pcsx2/DebugTools/Breakpoints.h @@ -24,7 +24,8 @@ struct BreakPointCond u32 Evaluate() { u64 result; - if (!debug->parseExpression(expression, result) || result == 0) + std::string error; + if (!debug->parseExpression(expression, result, error) || result == 0) return 0; return 1; } diff --git a/pcsx2/DebugTools/DebugInterface.cpp b/pcsx2/DebugTools/DebugInterface.cpp index 37da993322..8554ffa109 100644 --- a/pcsx2/DebugTools/DebugInterface.cpp +++ b/pcsx2/DebugTools/DebugInterface.cpp @@ -340,7 +340,7 @@ std::optional DebugInterface::getStackFrameSize(const ccc::Function& functi // The stack frame size isn't stored in the symbol table, so we try // to extract it from the code by checking for an instruction at the // start of the current function that is in the form of - // "addui $sp, $sp, frame_size" instead. + // "addiu $sp, $sp, frame_size" instead. u32 instruction = read32(function.address().value); @@ -354,29 +354,29 @@ std::optional DebugInterface::getStackFrameSize(const ccc::Function& functi return static_cast(stack_frame_size); } -bool DebugInterface::evaluateExpression(const char* expression, u64& dest) +bool DebugInterface::evaluateExpression(const char* expression, u64& dest, std::string& error) { PostfixExpression postfix; - if (!initExpression(expression, postfix)) + if (!initExpression(expression, postfix, error)) return false; - if (!parseExpression(postfix, dest)) + if (!parseExpression(postfix, dest, error)) return false; return true; } -bool DebugInterface::initExpression(const char* exp, PostfixExpression& dest) +bool DebugInterface::initExpression(const char* exp, PostfixExpression& dest, std::string& error) { MipsExpressionFunctions funcs(this, true); - return initPostfixExpression(exp, &funcs, dest); + return initPostfixExpression(exp, &funcs, dest, error); } -bool DebugInterface::parseExpression(PostfixExpression& exp, u64& dest) +bool DebugInterface::parseExpression(PostfixExpression& exp, u64& dest, std::string& error) { MipsExpressionFunctions funcs(this, false); - return parsePostfixExpression(exp, &funcs, dest); + return parsePostfixExpression(exp, &funcs, dest, error); } // @@ -904,12 +904,10 @@ std::vector> R5900DebugInterface::GetThreadList() co return getEEThreads(); } - // // R3000DebugInterface // - BreakPointCpu R3000DebugInterface::getCpuType() { return BREAKPOINT_IOP; diff --git a/pcsx2/DebugTools/DebugInterface.h b/pcsx2/DebugTools/DebugInterface.h index fceedb9fea..72111fe0ba 100644 --- a/pcsx2/DebugTools/DebugInterface.h +++ b/pcsx2/DebugTools/DebugInterface.h @@ -86,9 +86,9 @@ public: virtual SymbolImporter* GetSymbolImporter() const = 0; virtual std::vector> GetThreadList() const = 0; - bool evaluateExpression(const char* expression, u64& dest); - bool initExpression(const char* exp, PostfixExpression& dest); - bool parseExpression(PostfixExpression& exp, u64& dest); + bool evaluateExpression(const char* expression, u64& dest, std::string& error); + bool initExpression(const char* exp, PostfixExpression& dest, std::string& error); + bool parseExpression(PostfixExpression& exp, u64& dest, std::string& error); bool isAlive(); bool isCpuPaused(); void pauseCpu(); diff --git a/pcsx2/DebugTools/ExpressionParser.cpp b/pcsx2/DebugTools/ExpressionParser.cpp index 7fc0a8866b..211c76fe13 100644 --- a/pcsx2/DebugTools/ExpressionParser.cpp +++ b/pcsx2/DebugTools/ExpressionParser.cpp @@ -21,8 +21,6 @@ typedef enum { typedef enum { EXCOMM_CONST, EXCOMM_CONST_FLOAT, EXCOMM_REF, EXCOMM_OP } ExpressionCommand; -static std::string expressionError; - typedef struct { char Name[4]; unsigned char Priority; @@ -209,10 +207,8 @@ bool isAlphaNum(char c) c == '@' || c == '_' || c == '$' || c == '.'); } -bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest) +bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest, std::string& error) { - expressionError.clear(); - int infixPos = 0; int infixLen = (int)strlen(infix); ExpressionOpcodeType lastOpcode = EXOP_NONE; @@ -241,7 +237,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf if(subPos == sizeof(subStr) - 1) { - expressionError = TRANSLATE("ExpressionParser", "Token too long."); + error = TRANSLATE("ExpressionParser", "Token too long."); return false; } @@ -251,7 +247,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf isFloat = true; else if (!parseNumber(subStr,16,subPos,value)) { - expressionError = StringUtil::StdStringFromFormat( + error = StringUtil::StdStringFromFormat( TRANSLATE("ExpressionParser", "Invalid number \"%s\"."), subStr); return false; } @@ -268,7 +264,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf if(subPos == sizeof(subStr) - 1) { - expressionError = TRANSLATE("ExpressionParser", "Token too long."); + error = TRANSLATE("ExpressionParser", "Token too long."); return false; } @@ -294,7 +290,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf continue; } - expressionError = StringUtil::StdStringFromFormat( + error = StringUtil::StdStringFromFormat( TRANSLATE("ExpressionParser", "Invalid symbol \"%s\"."), subStr); return false; } else { @@ -302,7 +298,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf ExpressionOpcodeType type = getExpressionOpcode(&infix[infixPos],len,lastOpcode); if (type == EXOP_NONE) { - expressionError = StringUtil::StdStringFromFormat( + error = StringUtil::StdStringFromFormat( TRANSLATE("ExpressionParser", "Invalid operator at \"%s\"."), &infix[infixPos]); return false; } @@ -318,7 +314,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf { if (opcodeStack.empty()) { - expressionError = TRANSLATE("ExpressionParser", "Closing parenthesis without opening one."); + error = TRANSLATE("ExpressionParser", "Closing parenthesis without opening one."); return false; } ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; @@ -332,7 +328,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf { if (opcodeStack.empty()) { - expressionError = TRANSLATE("ExpressionParser", "Closing bracket without opening one."); + error = TRANSLATE("ExpressionParser", "Closing bracket without opening one."); return false; } ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; @@ -385,7 +381,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf if (t == EXOP_BRACKETL) // opening bracket without closing one { - expressionError = TRANSLATE("ExpressionParser", "Parenthesis not closed."); + error = TRANSLATE("ExpressionParser", "Parenthesis not closed."); return false; } dest.push_back(ExpressionPair(EXCOMM_OP,t)); @@ -415,7 +411,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf return true; } -bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest) +bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest, std::string& error) { size_t num = 0; u64 opcode; @@ -444,7 +440,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, opcode = exp[num++].second; if (valueStack.size() < ExpressionOpcodes[opcode].args) { - expressionError = TRANSLATE("ExpressionParser", "Not enough arguments."); + error = TRANSLATE("ExpressionParser", "Not enough arguments."); return false; } for (int l = 0; l < ExpressionOpcodes[opcode].args; l++) @@ -459,12 +455,12 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, case EXOP_MEMSIZE: // must be followed by EXOP_MEM if (exp[num++].second != EXOP_MEM) { - expressionError = TRANSLATE("ExpressionParser", "Invalid memsize operator."); + error = TRANSLATE("ExpressionParser", "Invalid memsize operator."); return false; } u64 val; - if(!funcs->getMemoryValue(arg[1],arg[0],val,expressionError)) + if(!funcs->getMemoryValue(arg[1],arg[0],val,error)) { return false; } @@ -473,7 +469,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, case EXOP_MEM: { u64 val; - if (!funcs->getMemoryValue(arg[0],4,val,expressionError)) + if (!funcs->getMemoryValue(arg[0],4,val,error)) { return false; } @@ -503,7 +499,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, case EXOP_DIV: // a/b if (arg[0] == 0) { - expressionError = TRANSLATE("ExpressionParser", "Division by zero."); + error = TRANSLATE("ExpressionParser", "Division by zero."); return false; } if (useFloat) @@ -514,7 +510,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, case EXOP_MOD: // a%b if (arg[0] == 0) { - expressionError = TRANSLATE("ExpressionParser", "Modulo by zero."); + error = TRANSLATE("ExpressionParser", "Modulo by zero."); return false; } valueStack.push_back(arg[1]%arg[0]); @@ -593,7 +589,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, case EXOP_TERTELSE: // exp ? exp : exp, else muss zuerst kommen! if (exp[num++].second != EXOP_TERTIF) { - expressionError = TRANSLATE("ExpressionParser", "Invalid tertiary operator."); + error = TRANSLATE("ExpressionParser", "Invalid tertiary operator."); return false; } valueStack.push_back(arg[2]?arg[1]:arg[0]); @@ -608,17 +604,9 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, return true; } -bool parseExpression(char* exp, IExpressionFunctions* funcs, u64& dest) +bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest, std::string& error) { PostfixExpression postfix; - if (!initPostfixExpression(exp,funcs,postfix)) return false; - return parsePostfixExpression(postfix,funcs,dest); -} - -const char* getExpressionError() -{ - if (expressionError.empty()) - return TRANSLATE("ExpressionParser", "Invalid expression."); - - return expressionError.c_str(); + if (!initPostfixExpression(exp,funcs,postfix,error)) return false; + return parsePostfixExpression(postfix,funcs,dest,error); } diff --git a/pcsx2/DebugTools/ExpressionParser.h b/pcsx2/DebugTools/ExpressionParser.h index a7f637149c..a34bc48573 100644 --- a/pcsx2/DebugTools/ExpressionParser.h +++ b/pcsx2/DebugTools/ExpressionParser.h @@ -26,7 +26,6 @@ public: virtual bool getMemoryValue(u32 address, int size, u64& dest, std::string& error) = 0; }; -bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest); -bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest); -bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest); -const char* getExpressionError(); +bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest, std::string& error); +bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest, std::string& error); +bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest, std::string& error); diff --git a/pcsx2/DebugTools/MipsAssembler.cpp b/pcsx2/DebugTools/MipsAssembler.cpp index 4edd01cdf0..5db774bf11 100644 --- a/pcsx2/DebugTools/MipsAssembler.cpp +++ b/pcsx2/DebugTools/MipsAssembler.cpp @@ -355,11 +355,12 @@ bool MipsCheckImmediate(const char* Source, DebugInterface* cpu, int& dest, int& RetLen = SourceLen; PostfixExpression postfix; - if (!cpu->initExpression(Buffer,postfix)) + std::string error; + if (!cpu->initExpression(Buffer,postfix,error)) return false; u64 value; - if (!cpu->parseExpression(postfix,value)) + if (!cpu->parseExpression(postfix,value,error)) return false; dest = (int) value;