- enhancement: Use asm highlighter in cpu window
- fix: "AT&T" radio button not correctly checked in cpu window - enhancement: Remove blank lines in the register list of cpu window. - fix: Cpu window's size not correctly saved, if it is not closed before app exits. - fix: Can't restore cpu window's splitter position.
This commit is contained in:
parent
f9fb966c38
commit
77942999d5
5
NEWS.md
5
NEWS.md
|
@ -17,6 +17,11 @@ Red Panda C++ Version 2.5
|
|||
- enhancement: Disable "run" and "debug" actions when current project is static or dynamic library
|
||||
- enhancement: Add "Generate Assembly" in "Run" Menu
|
||||
- enhancement: Improve highlighter for asm
|
||||
- enhancement: Use asm highlighter in cpu window
|
||||
- fix: "AT&T" radio button not correctly checked in cpu window
|
||||
- enhancement: Remove blank lines in the register list of cpu window.
|
||||
- fix: Cpu window's size not correctly saved, if it is not closed before app exits.
|
||||
- fix: Can't restore cpu window's splitter position.
|
||||
|
||||
Red Panda C++ Version 2.4
|
||||
|
||||
|
|
|
@ -1459,7 +1459,9 @@ void DebugReader::handleRegisterNames(const QList<GDBMIResultParser::ParseValue>
|
|||
{
|
||||
QStringList nameList;
|
||||
foreach (const GDBMIResultParser::ParseValue& nameValue, names) {
|
||||
nameList.append(nameValue.value());
|
||||
// QString text = nameValue.value().trimmed();
|
||||
// if (!text.isEmpty())
|
||||
nameList.append(nameValue.value());
|
||||
}
|
||||
emit registerNamesUpdated(nameList);
|
||||
}
|
||||
|
@ -2605,7 +2607,9 @@ QVariant RegisterModel::data(const QModelIndex &index, int role) const
|
|||
case 0:
|
||||
return mRegisterNames[index.row()];
|
||||
case 1:
|
||||
return mRegisterValues.value(index.row(),"");
|
||||
return mRegisterValues.value(
|
||||
mRegisterNameIndex.value(index.row(),-1)
|
||||
,"");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
@ -2630,7 +2634,15 @@ QVariant RegisterModel::headerData(int section, Qt::Orientation orientation, int
|
|||
void RegisterModel::updateNames(const QStringList ®Names)
|
||||
{
|
||||
beginResetModel();
|
||||
mRegisterNames = regNames;
|
||||
mRegisterNameIndex.clear();
|
||||
mRegisterNames.clear();
|
||||
for (int i=0;i<regNames.length();i++) {
|
||||
QString regName = regNames[i].trimmed();
|
||||
if (!regName.isEmpty()) {
|
||||
mRegisterNames.append(regNames[i]);
|
||||
mRegisterNameIndex.insert(mRegisterNames.count()-1,i);
|
||||
}
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,7 @@ public:
|
|||
void clear();
|
||||
private:
|
||||
QStringList mRegisterNames;
|
||||
QHash<int,int> mRegisterNameIndex;
|
||||
QHash<int,QString> mRegisterValues;
|
||||
};
|
||||
|
||||
|
|
|
@ -4925,6 +4925,8 @@ void MainWindow::on_actionOpen_triggered()
|
|||
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
mQuitting = true;
|
||||
if (!mShouldRemoveAllSettings) {
|
||||
if (mCPUDialog)
|
||||
mCPUDialog->close();
|
||||
Settings::UI& settings = pSettings->ui();
|
||||
settings.setMainWindowState(saveState());
|
||||
settings.setMainWindowGeometry(saveGeometry());
|
||||
|
|
|
@ -3745,7 +3745,6 @@ void Settings::Debugger::doSave()
|
|||
saveValue("gdb_server_port",mGDBServerPort);
|
||||
saveValue("memory_view_rows",mMemoryViewRows);
|
||||
saveValue("memory_view_columns",mMemoryViewColumns);
|
||||
|
||||
}
|
||||
|
||||
void Settings::Debugger::doLoad()
|
||||
|
|
|
@ -26,12 +26,13 @@
|
|||
|
||||
CPUDialog::CPUDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::CPUDialog)
|
||||
ui(new Ui::CPUDialog),
|
||||
mInited(false)
|
||||
{
|
||||
setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
setWindowFlag(Qt::WindowContextHelpButtonHint,false);
|
||||
ui->setupUi(this);
|
||||
ui->txtCode->setHighlighter(highlighterManager.getCppHighlighter());
|
||||
ui->txtCode->setHighlighter(highlighterManager.getAsmHighlighter());
|
||||
ui->txtCode->setReadOnly(true);
|
||||
ui->txtCode->gutter().setShowLineNumbers(false);
|
||||
ui->txtCode->setCaretUseTextColor(true);
|
||||
|
@ -40,6 +41,7 @@ CPUDialog::CPUDialog(QWidget *parent) :
|
|||
ui->txtCode->codeFolding().fillIndents = false;
|
||||
ui->txtCode->setGutterWidth(0);
|
||||
ui->txtCode->setUseCodeFolding(false);
|
||||
ui->txtCode->setRightEdge(0);
|
||||
highlighterManager.applyColorScheme(ui->txtCode->highlighter(),
|
||||
pSettings->editor().colorScheme());
|
||||
PColorSchemeItem item = pColorManager->getItem(pSettings->editor().colorScheme(),COLOR_SCHEME_ACTIVE_LINE);
|
||||
|
@ -60,17 +62,11 @@ CPUDialog::CPUDialog(QWidget *parent) :
|
|||
delete m;
|
||||
|
||||
ui->rdIntel->setChecked(pSettings->debugger().useIntelStyle());
|
||||
if (!ui->rdIntel->isChecked())
|
||||
ui->rdATT->setChecked(true);
|
||||
ui->chkBlendMode->setChecked(pSettings->debugger().blendMode());
|
||||
resize(pSettings->ui().CPUDialogWidth(),pSettings->ui().CPUDialogHeight());
|
||||
|
||||
QList<int> sizes = ui->splitter->sizes();
|
||||
int tabWidth = pSettings->ui().CPUDialogSplitterPos();
|
||||
int totalSize = sizes[0] + sizes[1];
|
||||
sizes[0] = tabWidth;
|
||||
sizes[1] = std::max(1,totalSize - sizes[0]);
|
||||
ui->splitter->setSizes(sizes);
|
||||
|
||||
onUpdateIcons();
|
||||
connect(pIconsManager,&IconsManager::actionIconsUpdated,
|
||||
this, &CPUDialog::onUpdateIcons);
|
||||
}
|
||||
|
@ -200,3 +196,18 @@ void CPUDialog::onUpdateIcons()
|
|||
pIconsManager->setIcon(ui->btnStepOverInstruction, IconsManager::ACTION_RUN_STEP_OVER_INSTRUCTION);
|
||||
}
|
||||
|
||||
void CPUDialog::showEvent(QShowEvent *event)
|
||||
{
|
||||
QDialog::showEvent(event);
|
||||
if (!mInited) {
|
||||
mInited=true;
|
||||
|
||||
QList<int> sizes = ui->splitter->sizes();
|
||||
int tabWidth = pSettings->ui().CPUDialogSplitterPos();
|
||||
int totalSize = sizes[0] + sizes[1];
|
||||
sizes[0] = tabWidth;
|
||||
sizes[1] = std::max(0,totalSize - sizes[0]);
|
||||
ui->splitter->setSizes(sizes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ private:
|
|||
void sendSyntaxCommand();
|
||||
private:
|
||||
Ui::CPUDialog *ui;
|
||||
bool mInited;
|
||||
// QWidget interface
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
@ -52,6 +53,10 @@ private slots:
|
|||
void on_btnStepOverInstruction_clicked();
|
||||
void on_btnStepIntoInstruction_clicked();
|
||||
void onUpdateIcons();
|
||||
|
||||
// QWidget interface
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
};
|
||||
|
||||
#endif // CPUDIALOG_H
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>3</horstretch>
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
|
@ -83,7 +83,7 @@
|
|||
<widget class="QSynedit::SynEdit" name="txtCode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<horstretch>3</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
|
@ -187,6 +187,12 @@
|
|||
</layout>
|
||||
</widget>
|
||||
<widget class="QTableView" name="lstRegister">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
|
|
|
@ -53,6 +53,7 @@ extern const QChar SoftBreakGlyph;
|
|||
#define SYNS_AttrSymbol "Symbol"
|
||||
#define SYNS_AttrVariable "Variable"
|
||||
#define SYNS_AttrSpace "Space"
|
||||
|
||||
// names of exporter output formats
|
||||
#define SYNS_ExporterFormatHTML "HTML"
|
||||
#define SYNS_ExporterFormatRTF "RTF"
|
||||
|
|
|
@ -20,6 +20,23 @@
|
|||
|
||||
namespace QSynedit {
|
||||
|
||||
const QSet<QString> ASMHighlighter::Registers {
|
||||
"ah","al","ax","eax",
|
||||
"bh","bl","bx","ebx",
|
||||
"ch","cl","cx","ecx",
|
||||
"dh","dl","dx","edx",
|
||||
"rax","rbx","rcx","rdx","rsi","rdi","rbp",
|
||||
"rsp","r8","r9","r10","r11","r12","r13","r14","r15",
|
||||
"r8h","r8l","r8w","r8d",
|
||||
"r9h","r9l","r9w","r9d",
|
||||
"r10h","r10l","r10w","r10d",
|
||||
"r11h","r11l","r11w","r11d",
|
||||
"r12h","r12l","r12w","r12d",
|
||||
"r13h","r13l","r13w","r13d",
|
||||
"r14h","r14l","r14w","r14d",
|
||||
"r15h","r15l","r15w","r15d"
|
||||
};
|
||||
|
||||
const QSet<QString> ASMHighlighter::Keywords {
|
||||
"movb","movw","movl","movq",
|
||||
"leab","leaw","leal","leaq",
|
||||
|
@ -83,13 +100,24 @@ ASMHighlighter::ASMHighlighter()
|
|||
{
|
||||
mNumberAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrNumber, TokenType::Number);
|
||||
addAttribute(mNumberAttribute);
|
||||
mDirectiveAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrVariable, TokenType::Keyword);
|
||||
addAttribute(mDirectiveAttribute);
|
||||
mLabelAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrFunction, TokenType::Keyword);
|
||||
addAttribute(mLabelAttribute);
|
||||
mRegisterAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrClass, TokenType::Keyword);
|
||||
addAttribute(mRegisterAttribute);
|
||||
}
|
||||
|
||||
PHighlighterAttribute ASMHighlighter::numberAttribute()
|
||||
const PHighlighterAttribute &ASMHighlighter::numberAttribute() const
|
||||
{
|
||||
return mNumberAttribute;
|
||||
}
|
||||
|
||||
const PHighlighterAttribute &ASMHighlighter::registerAttribute() const
|
||||
{
|
||||
return mRegisterAttribute;
|
||||
}
|
||||
|
||||
void ASMHighlighter::CommentProc()
|
||||
{
|
||||
mTokenID = TokenId::Comment;
|
||||
|
@ -114,17 +142,32 @@ void ASMHighlighter::GreaterProc()
|
|||
mRun++;
|
||||
}
|
||||
|
||||
void ASMHighlighter::IdentProc()
|
||||
void ASMHighlighter::IdentProc(IdentPrefix prefix)
|
||||
{
|
||||
int start = mRun;
|
||||
while (isIdentChar(mLine[mRun])) {
|
||||
mRun++;
|
||||
}
|
||||
QString s = mLineString.mid(start,mRun-start);
|
||||
if (Keywords.contains(s)) {
|
||||
mTokenID = TokenId::rainbow;
|
||||
} else {
|
||||
mTokenID = TokenId::Identifier;
|
||||
QString s = mLineString.mid(start,mRun-start).toLower();
|
||||
switch(prefix) {
|
||||
case IdentPrefix::Percent:
|
||||
mTokenID = TokenId::Register;
|
||||
break;
|
||||
case IdentPrefix::Period:
|
||||
if (mLine[mRun]==':')
|
||||
mTokenID = TokenId::Label;
|
||||
else
|
||||
mTokenID = TokenId::Directive;
|
||||
break;
|
||||
default:
|
||||
if (Keywords.contains(s))
|
||||
mTokenID = TokenId::Instruction;
|
||||
else if (Registers.contains(s))
|
||||
mTokenID = TokenId::Register;
|
||||
else if (mLine[mRun]==':')
|
||||
mTokenID = TokenId::Label;
|
||||
else
|
||||
mTokenID = TokenId::Identifier;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,7 +249,8 @@ void ASMHighlighter::StringProc()
|
|||
mTokenID = TokenId::String;
|
||||
if ((mRun+2 < mLineString.size()) && (mLine[mRun + 1] == '\"') && (mLine[mRun + 2] == '\"'))
|
||||
mRun += 2;
|
||||
mRun+=1;
|
||||
else
|
||||
mRun+=1;
|
||||
while (true) {
|
||||
if (mLine[mRun] == 0 || mLine[mRun] == '\r' || mLine[mRun] == '\n')
|
||||
break;
|
||||
|
@ -230,6 +274,20 @@ void ASMHighlighter::UnknownProc()
|
|||
mTokenID = TokenId::Unknown;
|
||||
}
|
||||
|
||||
bool ASMHighlighter::isIdentStartChar(const QChar &ch)
|
||||
{
|
||||
if (ch == '_') {
|
||||
return true;
|
||||
}
|
||||
if ((ch>='a') && (ch <= 'z')) {
|
||||
return true;
|
||||
}
|
||||
if ((ch>='A') && (ch <= 'Z')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ASMHighlighter::eol() const
|
||||
{
|
||||
return mTokenID == TokenId::Null;
|
||||
|
@ -257,8 +315,14 @@ PHighlighterAttribute ASMHighlighter::getTokenAttribute() const
|
|||
return mCommentAttribute;
|
||||
case TokenId::Identifier:
|
||||
return mIdentifierAttribute;
|
||||
case TokenId::rainbow:
|
||||
case TokenId::Instruction:
|
||||
return mKeywordAttribute;
|
||||
case TokenId::Directive:
|
||||
return mDirectiveAttribute;
|
||||
case TokenId::Label:
|
||||
return mLabelAttribute;
|
||||
case TokenId::Register:
|
||||
return mRegisterAttribute;
|
||||
case TokenId::Number:
|
||||
return mNumberAttribute;
|
||||
case TokenId::Space:
|
||||
|
@ -313,6 +377,19 @@ void ASMHighlighter::next()
|
|||
CommentProc();
|
||||
break;
|
||||
case '.':
|
||||
if (isIdentChar(mLine[mRun+1])) {
|
||||
mRun++;
|
||||
IdentProc(IdentPrefix::Period);
|
||||
} else
|
||||
SymbolProc();
|
||||
break;
|
||||
case '%':
|
||||
if (isIdentChar(mLine[mRun+1])) {
|
||||
mRun++;
|
||||
IdentProc(IdentPrefix::Percent);
|
||||
} else
|
||||
UnknownProc();
|
||||
break;
|
||||
case ':':
|
||||
case '&':
|
||||
case '{':
|
||||
|
@ -329,10 +406,8 @@ void ASMHighlighter::next()
|
|||
default:
|
||||
if (mLine[mRun]>='0' && mLine[mRun]<='9') {
|
||||
NumberProc();
|
||||
} else if ((mLine[mRun]>='A' && mLine[mRun]<='Z')
|
||||
|| (mLine[mRun]>='a' && mLine[mRun]<='z')
|
||||
|| (mLine[mRun]=='_')) {
|
||||
IdentProc();
|
||||
} else if (isIdentChar(mLine[mRun])) {
|
||||
IdentProc(IdentPrefix::None);
|
||||
} else if (mLine[mRun]<=32) {
|
||||
SpaceProc();
|
||||
} else {
|
||||
|
@ -384,4 +459,14 @@ QSet<QString> ASMHighlighter::keywords() const
|
|||
{
|
||||
return Keywords;
|
||||
}
|
||||
|
||||
const PHighlighterAttribute &ASMHighlighter::directiveAttribute() const
|
||||
{
|
||||
return mDirectiveAttribute;
|
||||
}
|
||||
|
||||
const PHighlighterAttribute &ASMHighlighter::labelAttribute() const
|
||||
{
|
||||
return mLabelAttribute;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,10 @@ class ASMHighlighter : public Highlighter
|
|||
enum class TokenId {
|
||||
Comment,
|
||||
Identifier,
|
||||
rainbow, // add mov etc
|
||||
Instruction, // add mov etc
|
||||
Directive, // .section .data etc
|
||||
Label,
|
||||
Register, //EAX EBX etc
|
||||
Null,
|
||||
Number,
|
||||
Space,
|
||||
|
@ -34,11 +37,21 @@ class ASMHighlighter : public Highlighter
|
|||
Symbol,
|
||||
Unknown
|
||||
};
|
||||
enum class IdentPrefix {
|
||||
None,
|
||||
Period,
|
||||
Percent
|
||||
};
|
||||
|
||||
public:
|
||||
explicit ASMHighlighter();
|
||||
PHighlighterAttribute numberAttribute();
|
||||
const PHighlighterAttribute &numberAttribute() const;
|
||||
const PHighlighterAttribute &directiveAttribute() const;
|
||||
const PHighlighterAttribute &labelAttribute() const;
|
||||
const PHighlighterAttribute ®isterAttribute() const;
|
||||
|
||||
static const QSet<QString> Keywords;
|
||||
static const QSet<QString> Registers;
|
||||
private:
|
||||
QChar* mLine;
|
||||
QString mLineString;
|
||||
|
@ -49,12 +62,15 @@ private:
|
|||
int mTokenPos;
|
||||
TokenId mTokenID;
|
||||
PHighlighterAttribute mNumberAttribute;
|
||||
PHighlighterAttribute mDirectiveAttribute;
|
||||
PHighlighterAttribute mRegisterAttribute;
|
||||
PHighlighterAttribute mLabelAttribute;
|
||||
|
||||
private:
|
||||
void CommentProc();
|
||||
void CRProc();
|
||||
void GreaterProc();
|
||||
void IdentProc();
|
||||
void IdentProc(IdentPrefix prefix);
|
||||
void LFProc();
|
||||
void LowerProc();
|
||||
void NullProc();
|
||||
|
@ -65,7 +81,7 @@ private:
|
|||
void StringProc();
|
||||
void SymbolProc();
|
||||
void UnknownProc();
|
||||
|
||||
bool isIdentStartChar(const QChar& ch);
|
||||
|
||||
// SynHighlighter interface
|
||||
public:
|
||||
|
@ -88,11 +104,10 @@ public:
|
|||
void setState(const HighlighterState& rangeState) override;
|
||||
void resetState() override;
|
||||
|
||||
// SynHighlighter interface
|
||||
|
||||
public:
|
||||
QSet<QString> keywords() const override;
|
||||
const PHighlighterAttribute &directiveAttribute() const;
|
||||
const PHighlighterAttribute &labelAttribute() const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue