diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index dd267a32..cf63e9d6 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -17,8 +17,8 @@ SOURCES += \ compiler/filecompiler.cpp \ compiler/stdincompiler.cpp \ parser/cpppreprocessor.cpp \ + parser/parserutils.cpp \ parser/statementmodel.cpp \ - parser/utils.cpp \ qsynedit/Search.cpp \ qsynedit/SearchBase.cpp \ qsynedit/SearchRegex.cpp \ @@ -77,8 +77,8 @@ HEADERS += \ compiler/filecompiler.h \ compiler/stdincompiler.h \ parser/cpppreprocessor.h \ + parser/parserutils.h \ parser/statementmodel.h \ - parser/utils.h \ qsynedit/Search.h \ qsynedit/SearchBase.h \ qsynedit/SearchRegex.h \ diff --git a/RedPandaIDE/debugger.cpp b/RedPandaIDE/debugger.cpp index df04953d..b416d8de 100644 --- a/RedPandaIDE/debugger.cpp +++ b/RedPandaIDE/debugger.cpp @@ -774,8 +774,9 @@ void DebugReader::handleDisassembly() s = getNextLine(); // Add lines of disassembly - while (!s.isEmpty() && (s != "End of assembler dump.")) { - mDisassembly.append(s); + while (s != "End of assembler dump.") { + if(!s.isEmpty()) + mDisassembly.append(s); s = getNextLine(); } diff --git a/RedPandaIDE/main.cpp b/RedPandaIDE/main.cpp index a9ab5c0c..502d8868 100644 --- a/RedPandaIDE/main.cpp +++ b/RedPandaIDE/main.cpp @@ -12,7 +12,7 @@ #include "common.h" #include "colorscheme.h" #include "iconsmanager.h" -#include "parser/utils.h" +#include "parser/parserutils.h" Settings* createAppSettings(const QString& filepath = QString()) { QString filename; @@ -44,7 +44,7 @@ Settings* createAppSettings(const QString& filepath = QString()) { return nullptr; } - new Settings(filename); + return new Settings(filename); } int main(int argc, char *argv[]) diff --git a/RedPandaIDE/parser/cpppreprocessor.cpp b/RedPandaIDE/parser/cpppreprocessor.cpp index b52c3ebe..5fee2ced 100644 --- a/RedPandaIDE/parser/cpppreprocessor.cpp +++ b/RedPandaIDE/parser/cpppreprocessor.cpp @@ -1,6 +1,7 @@ #include "cpppreprocessor.h" #include "../utils.h" +#include #include CppPreprocessor::CppPreprocessor(QObject *parent) : QObject(parent) @@ -46,9 +47,47 @@ void CppPreprocessor::addDefineByParts(const QString &name, const QString &args, } } -void CppPreprocessor::getDefineParts(const QString &Input, QString &name, QString &args, QString &value) +void CppPreprocessor::getDefineParts(const QString &input, QString &name, QString &args, QString &value) { + QString s = input.trimmed(); + name = ""; + args = ""; + value = ""; + // Rules: + // When the character before the first opening brace is nonblank, a function is defined. + // After that point, switch from name to args + // The value starts after the first blank character outside of the outermost () pair + + int i = 0; + int level = 0; + bool isFunction = false; + int argStart = 0; + while (i < s.length()) { + // When we find the first opening brace, check if this is a function define + if (s[i] == '(') { + level++; + if ((level == 1) && (!isFunction)) { // found a function define! + name = s.mid(0,i); + argStart = i; + isFunction = true; + } + } else if (s[i]==')') { + level--; + } else if (isSpaceChar(s[i]) && (level == 0)) { + break; + } + i++; + } + if (isFunction) { + // Name has already been found + args = s.mid(argStart,i-argStart); + //todo: expand macro (if already have) + } else { + name = s.mid(0,i); + args = ""; + } + value = removeGCCAttributes(s.mid(i+1).trimmed()); } void CppPreprocessor::addDefineByLine(const QString &line, bool hardCoded) @@ -65,6 +104,134 @@ void CppPreprocessor::addDefineByLine(const QString &line, bool hardCoded) addDefineByParts(name, args, value, hardCoded); } +PDefine CppPreprocessor::getDefine(const QString &name) +{ + return mDefines.value(name,PDefine()); +} + +PDefine CppPreprocessor::getHardDefine(const QString &name) +{ + return mHardDefines.value(name,PDefine()); +} + +void CppPreprocessor::reset() +{ + mResult.clear(); + + // Clear extracted data + mIncludes.clear(); + mBranchResults.clear(); + mCurrentIncludes.reset(); + mProcessed.clear(); + resetDefines(); // do not throw away hardcoded +} + +void CppPreprocessor::resetDefines() +{ + mDefines.clear(); + + mDefines.insert(mHardDefines); +} + +void CppPreprocessor::setScanOptions(bool parseSystem, bool parseLocal) +{ + mParseSystem = parseSystem; + mParseLocal=parseLocal; +} + +void CppPreprocessor::setIncludePaths(QStringList list) +{ + mIncludePaths = list; +} + +void CppPreprocessor::setProjectIncludePaths(QStringList list) +{ + mProjectIncludePaths = list; +} + +void CppPreprocessor::setScannedFileList(std::shared_ptr > list) +{ + mScannedFiles = list; +} + +void CppPreprocessor::setIncludesList(std::shared_ptr > list) +{ + mIncludesList = list; +} + +void CppPreprocessor::preprocess(const QString &fileName, QStringList buffer) +{ + mFileName = fileName; + reset(); + openInclude(fileName, buffer); + // StringsToFile(mBuffer,"f:\\buffer.txt"); + preprocessBuffer(); + // StringsToFile(mBuffer,"f:\\buffer.txt"); + // StringsToFile(mResult,"f:\\log.txt"); +} + +void CppPreprocessor::invalidDefinesInFile(const QString &fileName) +{ + PDefineMap defineMap = mFileDefines.value(fileName,PDefineMap()); + if (defineMap) { + for (PDefine define:*defineMap) { + PDefine p = mDefines.value(define->name); + if (p == define) { + mDefines.remove(define->name); + } + } + mFileDefines.remove(fileName); + } +} + +void CppPreprocessor::dumpDefinesTo(const QString &fileName) +{ + QFile file(fileName); + if (file.open(QIODevice::WriteOnly|QIODevice::Truncate)) { + QTextStream stream(&file); + for (PDefine define:mDefines) { + stream<name) + .arg(define->args).arg(define->value) + .arg(define->hardCoded)<baseFile<<" : "<includeFiles.keys()) { + stream<<"\t--"+s<dependingFiles) { + stream<<"\t^^"+s<dependedFiles) { + stream<<"\t&&"+s<usings) { + stream<<"\t++"+s< p:fileIncludes->statements) { + PStatement statement = p.lock(); + if (statement) { + stream<command) + .arg(statement->fullName)<args=="" ) { //newLine:=newLine+RemoveGCCAttributes(define^.Value); if (define->value != word ) @@ -441,7 +604,7 @@ void CppPreprocessor::openInclude(const QString &fileName, QStringList bufferedT //mCurrentIncludes->scopes; //mCurrentIncludes->dependedFiles; //mCurrentIncludes->dependingFiles; - mIncludesList.insert(fileName,mCurrentIncludes); + mIncludesList->insert(fileName,mCurrentIncludes); } parsedFile->fileIncludes = mCurrentIncludes; @@ -529,6 +692,11 @@ bool CppPreprocessor::getCurrentBranch() return true; } +void CppPreprocessor::setCurrentBranch(bool value) +{ + mBranchResults.append(value); +} + void CppPreprocessor::removeCurrentBranch() { if (mBranchResults.size()>0) @@ -542,7 +710,7 @@ QStringList CppPreprocessor::getResult() PFileIncludes CppPreprocessor::getFileIncludesEntry(const QString &fileName) { - return mIncludesList.value(fileName,PFileIncludes()); + return mIncludesList->value(fileName,PFileIncludes()); } void CppPreprocessor::addDefinesInFile(const QString &fileName) @@ -921,8 +1089,7 @@ QString CppPreprocessor::expandDefines(QString line) tail++; } name = line.mid(defineStart, defineEnd - defineStart); - int dummy; - PDefine define = getDefine(name,dummy); + PDefine define = getDefine(name); QString insertValue; if (!define) { insertValue = "0"; @@ -937,8 +1104,7 @@ QString CppPreprocessor::expandDefines(QString line) } else { // We have found a regular define. Replace it by its value // Does it exist in the database? - int dummy; - PDefine define = getDefine(name,dummy); + PDefine define = getDefine(name); QString insertValue; if (!define) { insertValue = "0"; diff --git a/RedPandaIDE/parser/cpppreprocessor.h b/RedPandaIDE/parser/cpppreprocessor.h index 0f18a89f..2aebac18 100644 --- a/RedPandaIDE/parser/cpppreprocessor.h +++ b/RedPandaIDE/parser/cpppreprocessor.h @@ -3,7 +3,7 @@ #include #include -#include "utils.h" +#include "parserutils.h" #define MAX_DEFINE_EXPAND_DEPTH 20 @@ -37,20 +37,22 @@ public: void clear(); void addDefineByParts(const QString& name, const QString& args, const QString& value, bool hardCoded); - void getDefineParts(const QString& Input, QString &name, QString &args, QString &value); + void getDefineParts(const QString& input, QString &name, QString &args, QString &value); void addDefineByLine(const QString& line, bool hardCoded); - PDefine getDefine(const QString& name, int &index); - PDefine getHardDefine(const QString& name, int &index); + PDefine getDefine(const QString& name); + PDefine getHardDefine(const QString& name); void reset(); //reset but don't clear generated defines void resetDefines(); void setScanOptions(bool parseSystem, bool parseLocal); - void setIncludePaths(QStringList &list); - void setProjectIncludePaths(QStringList& list); - void setScannedFileList(QStringList &list); - void setIncludesList(QString& list); - void preprocessStream(const QString& fileName, QTextStream stream = QTextStream()); - void preprocessFile(const QString& fileName); + void setIncludePaths(QStringList list); + void setProjectIncludePaths(QStringList list); + void setScannedFileList(std::shared_ptr> list); + void setIncludesList(std::shared_ptr> list); + void preprocess(const QString& fileName, QStringList buffer = QStringList()); void invalidDefinesInFile(const QString& fileName); + + void dumpDefinesTo(const QString& fileName); + void dumpIncludesListTo(const QString& fileName); signals: private: @@ -153,7 +155,7 @@ private: QStringList mResult; PFileIncludes mCurrentIncludes; int mPreProcIndex; - QHash mIncludesList; + std::shared_ptr> mIncludesList; DefineMap mHardDefines; // set by "cpp -dM -E -xc NUL" DefineMap mDefines; // working set, editable QHash mFileDefines; //dictionary to save defines for each headerfile; diff --git a/RedPandaIDE/parser/utils.cpp b/RedPandaIDE/parser/parserutils.cpp similarity index 92% rename from RedPandaIDE/parser/utils.cpp rename to RedPandaIDE/parser/parserutils.cpp index 8c2a2367..d40f7244 100644 --- a/RedPandaIDE/parser/utils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -1,4 +1,4 @@ -#include "utils.h" +#include "parserutils.h" #include #include @@ -297,3 +297,33 @@ QString getSystemHeaderFileName(const QString &fileName, const QStringList& incl //not found return ""; } + +bool isSystemHeaderFile(const QString &fileName, const QStringList &includePaths) +{ + if (includePaths.isEmpty()) + return false; + bool isFullName = false; +#ifdef Q_OS_WIN + isFullName = fileName.length()>2 && fileName[1]==':'; +#else + isFullName = fileName.startsWith("\""); +#endif + if (isFullName) { + // If it's a full file name, check if its directory is an include path + QFileInfo info(fileName); + if (info.exists()) { // full file name + QDir dir = info.dir(); + QString absPath = dir.absolutePath(); + if (includePaths.indexOf(absPath)>=0) + return true; + } + } else { + //check if it's in the include dir + for (QString includePath: includePaths) { + QDir dir(includePath); + if (dir.exists(fileName)) + return true; + } + } + return false; +} diff --git a/RedPandaIDE/parser/utils.h b/RedPandaIDE/parser/parserutils.h similarity index 98% rename from RedPandaIDE/parser/utils.h rename to RedPandaIDE/parser/parserutils.h index 8dce390f..804b0641 100644 --- a/RedPandaIDE/parser/utils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -168,4 +168,5 @@ QString getHeaderFileName(const QString& relativeTo, const QString& line, QString getLocalHeaderFileName(const QString& relativeTo, const QString& fileName); QString getSystemHeaderFileName(const QString& fileName, const QStringList& includePaths); +bool isSystemHeaderFile(const QString& fileName, const QStringList& includePaths); #endif // PARSER_UTILS_H diff --git a/RedPandaIDE/parser/statementmodel.h b/RedPandaIDE/parser/statementmodel.h index a5f4cda9..b2f3e448 100644 --- a/RedPandaIDE/parser/statementmodel.h +++ b/RedPandaIDE/parser/statementmodel.h @@ -3,7 +3,7 @@ #include #include -#include "utils.h" +#include "parserutils.h" class StatementModel : public QObject { diff --git a/RedPandaIDE/qsynedit/highlighter/asm.cpp b/RedPandaIDE/qsynedit/highlighter/asm.cpp index 1b2897fb..635d5735 100644 --- a/RedPandaIDE/qsynedit/highlighter/asm.cpp +++ b/RedPandaIDE/qsynedit/highlighter/asm.cpp @@ -125,7 +125,7 @@ void SynEditASMHighlighter::NumberProc() mTokenID = TokenKind::Number; while (true) { QChar ch = mLine[mRun]; - if (!((ch>=0 && ch<=9) || (ch=='.') || (ch >= 'a' && ch<='f') + if (!((ch>='0' && ch<='9') || (ch=='.') || (ch >= 'a' && ch<='f') || (ch=='h') || (ch >= 'A' && ch<='F') || (ch == 'H'))) break; mRun++; diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index 6acb04e7..14362f81 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -2308,6 +2308,16 @@ void Settings::Debugger::setFontName(const QString &fontName) mFontName = fontName; } +bool Settings::Debugger::blendMode() const +{ + return mBlendMode; +} + +void Settings::Debugger::setBlendMode(bool blendMode) +{ + mBlendMode = blendMode; +} + bool Settings::Debugger::useIntelStyle() const { return mUseIntelStyle; @@ -2345,7 +2355,8 @@ void Settings::Debugger::doSave() saveValue("font_name",mFontName); saveValue("only_show_mono",mOnlyShowMono); saveValue("font_size",mFontSize); - boolValue("use_intel_style",mUseIntelStyle); + saveValue("use_intel_style",mUseIntelStyle); + saveValue("blend_mode",mBlendMode); } void Settings::Debugger::doLoad() @@ -2356,6 +2367,7 @@ void Settings::Debugger::doLoad() mOnlyShowMono = boolValue("only_show_mono",true); mFontSize = intValue("font_size",10); mUseIntelStyle = boolValue("use_intel_style",true); + mBlendMode = boolValue("blend_mode",true); } Settings::History::History(Settings *settings):_Base(settings, SETTING_HISTORY) diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h index 455b2432..4aa11305 100644 --- a/RedPandaIDE/settings.h +++ b/RedPandaIDE/settings.h @@ -429,6 +429,9 @@ public: QString fontName() const; void setFontName(const QString &fontName); + bool blendMode() const; + void setBlendMode(bool blendMode); + private: bool mShowCommandLog; bool mShowAnnotations; @@ -436,6 +439,7 @@ public: bool mOnlyShowMono; int mFontSize; bool mUseIntelStyle; + bool mBlendMode; // _Base interface protected: diff --git a/RedPandaIDE/settingsdialog/debuggeneralwidget.cpp b/RedPandaIDE/settingsdialog/debuggeneralwidget.cpp index 97599cf9..379f7794 100644 --- a/RedPandaIDE/settingsdialog/debuggeneralwidget.cpp +++ b/RedPandaIDE/settingsdialog/debuggeneralwidget.cpp @@ -27,6 +27,7 @@ void DebugGeneralWidget::doLoad() } else { ui->rbATT->setChecked(true); } + ui->chkBlendMode->setChecked(pSettings->debugger().blendMode()); } void DebugGeneralWidget::doSave() @@ -37,6 +38,7 @@ void DebugGeneralWidget::doSave() pSettings->debugger().setShowCommandLog(ui->chkShowLog->isChecked()); pSettings->debugger().setShowAnnotations(ui->chkShowFullAnnotation->isChecked()); pSettings->debugger().setUseIntelStyle(ui->rbIntel->isChecked()); + pSettings->debugger().setBlendMode(ui->chkBlendMode->isChecked()); pSettings->debugger().save(); pMainWindow->updateDebuggerSettings(); diff --git a/RedPandaIDE/settingsdialog/debuggeneralwidget.ui b/RedPandaIDE/settingsdialog/debuggeneralwidget.ui index a9adc70e..5c31b062 100644 --- a/RedPandaIDE/settingsdialog/debuggeneralwidget.ui +++ b/RedPandaIDE/settingsdialog/debuggeneralwidget.ui @@ -156,24 +156,92 @@ 11 + + + + + + + CPU Window + + - - - Intel - - - grpCPUDisassembly - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Disassembly Coding Style: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Intel + + + grpCPUDisassembly + + + + + + + AT&&T + + + grpCPUDisassembly + + + + + + + - + - AT&&T + Show disassembly code in blend mode - - grpCPUDisassembly - diff --git a/RedPandaIDE/utils.cpp b/RedPandaIDE/utils.cpp index 336a5e9b..264b688a 100644 --- a/RedPandaIDE/utils.cpp +++ b/RedPandaIDE/utils.cpp @@ -489,3 +489,14 @@ QStringList ReadFileToLines(const QString &fileName) } return result; } + +void StringsToFile(const QStringList &list, const QString &fileName) +{ + QFile file(fileName); + if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + QTextStream stream(&file); + for (QString s:list) { + stream<setupUi(this); - ui->txtCode->setHighlighter(highlighterManager.getAsmHighlighter()); + ui->txtCode->setHighlighter(highlighterManager.getCppHighlighter()); highlighterManager.applyColorScheme(ui->txtCode->highlighter(), pSettings->editor().colorScheme()); + PColorSchemeItem item = pColorManager->getItem(pSettings->editor().colorScheme(),COLOR_SCHEME_ACTIVE_LINE); + if (item) { + ui->txtCode->setActiveLineColor(item->background()); + } ui->lstRegister->setModel(pMainWindow->debugger()->registerModel()); - ui->rdIntel->setChecked(true); + ui->rdIntel->setChecked(pSettings->debugger().useIntelStyle()); + ui->chkBlendMode->setChecked(pSettings->debugger().blendMode()); // RadioATT.Checked := devData.UseATTSyntax; // RadioIntel.Checked := not devData.UseATTSyntax; // fRegisters := TList.Create; // fAssembler := TStringList.Create; - updateInfo(); + //updateInfo(); } CPUDialog::~CPUDialog() @@ -35,7 +42,10 @@ void CPUDialog::updateInfo() // Load the registers.. sendSyntaxCommand(); pMainWindow->debugger()->sendCommand("info", "registers"); - pMainWindow->debugger()->sendCommand("disas", ""); + if (ui->chkBlendMode->isChecked()) + pMainWindow->debugger()->sendCommand("disas", "/s"); + else + pMainWindow->debugger()->sendCommand("disas", ""); } } @@ -45,6 +55,7 @@ void CPUDialog::setDisassembly(const QStringList &lines) ui->txtFunctionName->setText(lines[0]); } int activeLine = -1; + ui->txtCode->lines()->clear(); for (int i=1;i")) { @@ -85,3 +96,10 @@ void CPUDialog::on_rdATT_toggled(bool) pSettings->debugger().setUseIntelStyle(ui->rdIntel->isChecked()); pSettings->debugger().save(); } + +void CPUDialog::on_chkBlendMode_stateChanged(int arg1) +{ + updateInfo(); + pSettings->debugger().setBlendMode(ui->chkBlendMode->isCheckable()); + pSettings->debugger().save(); +} diff --git a/RedPandaIDE/widgets/cpudialog.h b/RedPandaIDE/widgets/cpudialog.h index c8de9777..870e2af8 100644 --- a/RedPandaIDE/widgets/cpudialog.h +++ b/RedPandaIDE/widgets/cpudialog.h @@ -28,6 +28,7 @@ protected: private slots: void on_rdIntel_toggled(bool checked); void on_rdATT_toggled(bool checked); + void on_chkBlendMode_stateChanged(int arg1); }; #endif // CPUDIALOG_H diff --git a/RedPandaIDE/widgets/cpudialog.ui b/RedPandaIDE/widgets/cpudialog.ui index 60101614..36dbcfdf 100644 --- a/RedPandaIDE/widgets/cpudialog.ui +++ b/RedPandaIDE/widgets/cpudialog.ui @@ -143,6 +143,13 @@ + + + + Blend Mode + + +