- 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:
Roy Qu 2022-12-02 10:19:03 +08:00
parent f9fb966c38
commit 77942999d5
11 changed files with 178 additions and 36 deletions

View File

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

View File

@ -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 &regNames)
{
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();
}

View File

@ -113,6 +113,7 @@ public:
void clear();
private:
QStringList mRegisterNames;
QHash<int,int> mRegisterNameIndex;
QHash<int,QString> mRegisterValues;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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