From 738faf0c908bb208f1236fc370aad3fb344af594 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Sun, 13 Aug 2023 14:46:53 +0800 Subject: [PATCH] - fix: Crash if close file while auto syntax checking. - enhancement: support sdcc compiler. --- NEWS.md | 1 + RedPandaIDE/compiler/compiler.cpp | 123 +++++----- RedPandaIDE/compiler/compiler.h | 10 +- RedPandaIDE/compiler/compilerinfo.cpp | 127 +++++++++- RedPandaIDE/compiler/compilerinfo.h | 26 +- RedPandaIDE/editor.cpp | 41 +++- RedPandaIDE/editor.h | 1 + RedPandaIDE/mainwindow.cpp | 21 +- RedPandaIDE/parser/cppparser.cpp | 33 ++- RedPandaIDE/parser/parserutils.cpp | 23 ++ RedPandaIDE/parser/parserutils.h | 5 +- RedPandaIDE/settings.cpp | 231 +++++++++++++----- RedPandaIDE/settings.h | 6 +- .../compilersetoptionwidget.cpp | 17 +- .../settingsdialog/compilersetoptionwidget.ui | 2 +- RedPandaIDE/systemconsts.h | 3 + 16 files changed, 513 insertions(+), 157 deletions(-) diff --git a/NEWS.md b/NEWS.md index 4eb01522..48e48844 100644 --- a/NEWS.md +++ b/NEWS.md @@ -27,6 +27,7 @@ Red Panda C++ Version 2.24 - fix: Wrong compiler settings if xcode is not installed in mac os. - enhancement: Name for new files will not be different from files openned. - fix: Crash if close file while auto syntax checking. + - enhancement: support sdcc compiler. Red Panda C++ Version 2.23 diff --git a/RedPandaIDE/compiler/compiler.cpp b/RedPandaIDE/compiler/compiler.cpp index 770cefef..29633c71 100644 --- a/RedPandaIDE/compiler/compiler.cpp +++ b/RedPandaIDE/compiler/compiler.cpp @@ -41,8 +41,10 @@ Compiler::Compiler(const QString &filename, bool silent, bool onlyCheckSyntax): mSilent(silent), mOnlyCheckSyntax(onlyCheckSyntax), mFilename(filename), - mRebuild(false) + mRebuild(false), + mParser() { + getParserForFile(filename); } void Compiler::run() @@ -170,11 +172,12 @@ CompileIssueType Compiler::getIssueTypeFromOutputLine(QString &line) int pos = line.indexOf(':'); if (pos>=0) { QString s=line.mid(0,pos); - if (s == "error" || s == "fatal error") { + if (s == "error" || s == "fatal error" + || s == "syntax error") { mErrorCount += 1; line = tr("[Error] ")+line.mid(pos+1); result = CompileIssueType::Error; - } else if (s == "warning") { + } else if (s.startsWith("warning")) { mWarningCount += 1; line = tr("[Warning] ")+line.mid(pos+1); result = CompileIssueType::Warning; @@ -322,30 +325,25 @@ QString Compiler::getCharsetArgument(const QByteArray& encoding,FileType fileTyp bool forceExecUTF8=false; // test if force utf8 from autolink infos if ((fileType == FileType::CSource || - fileType == FileType::CppSource) && pSettings->editor().enableAutolink() ){ - Editor* editor = pMainWindow->editorList()->getOpenedEditorByFilename(mFilename); - if (editor) { - PCppParser parser = editor->parser(); - if (parser) { - int waitCount = 0; - //wait parsing ends, at most 1 second - while(parser->parsing()) { - if (waitCount>10) - break; - waitCount++; - QThread::msleep(100); - QApplication *app=dynamic_cast( - QApplication::instance()); - app->processEvents(); - } - QSet parsedFiles; - forceExecUTF8 = parseForceUTF8ForAutolink( - mFilename, - parsedFiles, - parser); - } + fileType == FileType::CppSource) && pSettings->editor().enableAutolink() + && mParser){ + int waitCount = 0; + //wait parsing ends, at most 1 second + while(mParser->parsing()) { + if (waitCount>10) + break; + waitCount++; + QThread::msleep(100); + QApplication *app=dynamic_cast( + QApplication::instance()); + app->processEvents(); + } + if (waitCount<=10) { + QSet parsedFiles; + forceExecUTF8 = parseForceUTF8ForAutolink( + mFilename, + parsedFiles); } - } if ((forceExecUTF8 || compilerSet()->autoAddCharsetParams()) && encoding != ENCODING_ASCII && compilerSet()->compilerType()!=CompilerType::Clang) { @@ -517,30 +515,25 @@ QString Compiler::getLibraryArguments(FileType fileType) //Add auto links // is file and auto link enabled if (pSettings->editor().enableAutolink() && (fileType == FileType::CSource || - fileType == FileType::CppSource)){ - Editor* editor = pMainWindow->editorList()->getEditor(); - if (editor) { - PCppParser parser = editor->parser(); - if (parser) { - int waitCount = 0; - //wait parsing ends, at most 1 second - while(parser->parsing()) { - if (waitCount>10) - break; - waitCount++; - QThread::msleep(100); - QApplication *app=dynamic_cast( - QApplication::instance()); - app->processEvents(); - } - QSet parsedFiles; - result += parseFileIncludesForAutolink( - editor->filename(), - parsedFiles, - parser); - } + fileType == FileType::CppSource) + && mParser){ + int waitCount = 0; + //wait parsing ends, at most 1 second + while(mParser->parsing()) { + if (waitCount>10) + break; + waitCount++; + QThread::msleep(100); + QApplication *app=dynamic_cast( + QApplication::instance()); + app->processEvents(); + } + if (waitCount<=10) { + QSet parsedFiles; + result += parseFileIncludesForAutolink( + mFilename, + parsedFiles); } - } //add compiler set link options @@ -600,8 +593,7 @@ QString Compiler::getLibraryArguments(FileType fileType) QString Compiler::parseFileIncludesForAutolink( const QString &filename, - QSet& parsedFiles, - PCppParser& parser) + QSet& parsedFiles) { QString result; if (parsedFiles.contains(filename)) @@ -611,7 +603,7 @@ QString Compiler::parseFileIncludesForAutolink( if (autolink) { result += ' '+autolink->linkOption; } - QStringList includedFiles = parser->getFileDirectIncludes(filename); + QStringList includedFiles = mParser->getFileDirectIncludes(filename); // log(QString("File %1 included:").arg(filename)); // for (int i=includedFiles.size()-1;i>=0;i--) { // QString includeFilename = includedFiles[i]; @@ -622,13 +614,12 @@ QString Compiler::parseFileIncludesForAutolink( QString includeFilename = includedFiles[i]; result += parseFileIncludesForAutolink( includeFilename, - parsedFiles, - parser); + parsedFiles); } return result; } -bool Compiler::parseForceUTF8ForAutolink(const QString &filename, QSet &parsedFiles, PCppParser &parser) +bool Compiler::parseForceUTF8ForAutolink(const QString &filename, QSet &parsedFiles) { bool result; if (parsedFiles.contains(filename)) @@ -638,7 +629,7 @@ bool Compiler::parseForceUTF8ForAutolink(const QString &filename, QSet if (autolink && autolink->execUseUTF8) { return true; } - QStringList includedFiles = parser->getFileDirectIncludes(filename); + QStringList includedFiles = mParser->getFileDirectIncludes(filename); // log(QString("File %1 included:").arg(filename)); // for (int i=includedFiles.size()-1;i>=0;i--) { // QString includeFilename = includedFiles[i]; @@ -649,8 +640,7 @@ bool Compiler::parseForceUTF8ForAutolink(const QString &filename, QSet QString includeFilename = includedFiles[i]; result = parseForceUTF8ForAutolink( includeFilename, - parsedFiles, - parser); + parsedFiles); if (result) return true; } @@ -750,6 +740,23 @@ void Compiler::runCommand(const QString &cmd, const QString &arguments, const Q } } +PCppParser Compiler::parser() const +{ + return mParser; +} + +void Compiler::getParserForFile(const QString &filename) +{ + FileType fileType = getFileType(filename); + if (fileType == FileType::CSource || + fileType == FileType::CppSource){ + Editor* editor = pMainWindow->editorList()->getOpenedEditorByFilename(filename); + if (editor && editor->parser()) { + mParser=editor->parser(); + } + } +} + const std::shared_ptr &Compiler::project() const { return mProject; diff --git a/RedPandaIDE/compiler/compiler.h b/RedPandaIDE/compiler/compiler.h index 8cc493c8..11eb545b 100644 --- a/RedPandaIDE/compiler/compiler.h +++ b/RedPandaIDE/compiler/compiler.h @@ -44,6 +44,8 @@ public: const std::shared_ptr &project() const; void setProject(const std::shared_ptr &newProject); + PCppParser parser() const; + signals: void compileStarted(); void compileFinished(QString filename); @@ -56,6 +58,7 @@ public slots: protected: void run() override; void processOutput(QString& line); + void getParserForFile(const QString& filename); virtual QString getFileNameFromOutputLine(QString &line); virtual int getLineNumberFromOutputLine(QString &line); virtual int getColunmnFromOutputLine(QString &line); @@ -75,12 +78,10 @@ protected: virtual QString getLibraryArguments(FileType fileType); virtual QString parseFileIncludesForAutolink( const QString& filename, - QSet& parsedFiles, - PCppParser& parser); + QSet& parsedFiles); virtual bool parseForceUTF8ForAutolink( const QString& filename, - QSet& parsedFiles, - PCppParser& parser); + QSet& parsedFiles); void log(const QString& msg); void error(const QString& msg); void runCommand(const QString& cmd, const QString& arguments, const QString& workingDir, const QByteArray& inputText=QByteArray()); @@ -101,6 +102,7 @@ protected: bool mRebuild; std::shared_ptr mProject; bool mSetLANG; + PCppParser mParser; private: bool mStop; diff --git a/RedPandaIDE/compiler/compilerinfo.cpp b/RedPandaIDE/compiler/compilerinfo.cpp index ed3d00ae..69a2c5cd 100644 --- a/RedPandaIDE/compiler/compilerinfo.cpp +++ b/RedPandaIDE/compiler/compilerinfo.cpp @@ -27,6 +27,11 @@ bool CompilerInfo::hasCompilerOption(const QString &key) const return mCompilerOptions.contains(key); } +bool CompilerInfo::supportSyntaxCheck() +{ + return true; +} + void CompilerInfo::addOption(const QString &key, const QString &name, const QString section, bool isC, bool isCpp, bool isLinker, const QString &setting, const CompileOptionChoiceList &choices) { PCompilerOption pOption = std::make_shared(); @@ -197,18 +202,7 @@ CompilerInfoManager::CompilerInfoManager() mInfos.insert(CompilerType::Clang, std::make_shared()); mInfos.insert(CompilerType::GCC, std::make_shared()); mInfos.insert(CompilerType::GCC_UTF8, std::make_shared()); -} - -bool CompilerInfoManager::supportSyntaxCheck(CompilerType compilerType) -{ - switch(compilerType) { - case CompilerType::GCC: - case CompilerType::GCC_UTF8: - case CompilerType::Clang: - return true; - default: - return false; - } + mInfos.insert(CompilerType::SDCC, std::make_shared()); } PCompilerInfo CompilerInfoManager::getInfo(CompilerType compilerType) @@ -248,6 +242,22 @@ bool CompilerInfoManager::supportCovertingCharset(CompilerType compilerType) return pInfo->supportConvertingCharset(); } +bool CompilerInfoManager::supportStaticLink(CompilerType compilerType) +{ + PCompilerInfo pInfo = getInfo(compilerType); + if (!pInfo) + return false; + return pInfo->supportStaticLink(); +} + +bool CompilerInfoManager::supportSyntaxCheck(CompilerType compilerType) +{ + PCompilerInfo pInfo = getInfo(compilerType); + if (!pInfo) + return false; + return pInfo->supportSyntaxCheck(); +} + bool CompilerInfoManager::forceUTF8InDebugger(CompilerType compilerType) { PCompilerInfo pInfo = getInfo(compilerType); @@ -290,6 +300,11 @@ bool ClangCompilerInfo::forceUTF8InMakefile() return false; } +bool ClangCompilerInfo::supportStaticLink() +{ + return true; +} + GCCCompilerInfo::GCCCompilerInfo():CompilerInfo(COMPILER_GCC) { } @@ -309,6 +324,11 @@ bool GCCCompilerInfo::forceUTF8InMakefile() return false; } +bool GCCCompilerInfo::supportStaticLink() +{ + return true; +} + GCCUTF8CompilerInfo::GCCUTF8CompilerInfo():CompilerInfo(COMPILER_GCC_UTF8) { } @@ -327,3 +347,86 @@ bool GCCUTF8CompilerInfo::forceUTF8InMakefile() { return true; } + +bool GCCUTF8CompilerInfo::supportStaticLink() +{ + return true; +} + +SDCCCompilerInfo::SDCCCompilerInfo():CompilerInfo(COMPILER_SDCC) +{ + +} + +bool SDCCCompilerInfo::supportConvertingCharset() +{ + return false; +} + +bool SDCCCompilerInfo::forceUTF8InDebugger() +{ + return false; +} + +bool SDCCCompilerInfo::forceUTF8InMakefile() +{ + return false; +} + +bool SDCCCompilerInfo::supportStaticLink() +{ + return false; +} + +bool SDCCCompilerInfo::supportSyntaxCheck() +{ + return false; +} + +void SDCCCompilerInfo::prepareCompilerOptions() +{ + QList> sl; + QString groupName; +// // C options +// groupName = QObject::tr("C options"); +// addOption(CC_CMD_OPT_ANSI, QObject::tr("Support all ANSI standard C programs (-ansi)"), groupName, true, true, false, "-ansi"); +// addOption(CC_CMD_OPT_NO_ASM, QObject::tr("Do not recognize asm,inline or typeof as a keyword (-fno-asm)"), groupName, true, true, false, "-fno-asm"); +// addOption(CC_CMD_OPT_TRADITIONAL_CPP, QObject::tr("Imitate traditional C preprocessors (-traditional-cpp)"), groupName, true, true, false, "-traditional-cpp"); + + groupName = QObject::tr("Code Generation"); + // Optimization + sl.clear(); + sl.append(QPair("Intel MCS51","mcs51")); + sl.append(QPair("Dallas DS80C390","ds390")); + sl.append(QPair("Dallas DS80C400","ds400")); + sl.append(QPair("Freescale/Motorola HC08","hc08")); + sl.append(QPair("Freescale/Motorola S08","s08")); + sl.append(QPair("Zilog Z80","z80")); + sl.append(QPair("Zilog Z180","z180")); + sl.append(QPair("Rabbit 2000/3000","r2k")); + sl.append(QPair("Rabbit 3000","r3ka")); + sl.append(QPair("Sharp SM83","sm83")); + sl.append(QPair("Toshiba TLCS-90","tlcs90")); + sl.append(QPair("Zilog eZ80","ez80_z80")); + sl.append(QPair("STM8","stm8")); + sl.append(QPair("Padauk processors with 13 bit wide program memory","pdk13")); + sl.append(QPair("Padauk processors with 14 bit wide program memory","pdk14")); + sl.append(QPair("Padauk processors with 15 bit wide program memory","pdk15")); + sl.append(QPair("Padauk processors with 15 bit wide program memory","pdk15")); + sl.append(QPair("Padauk processors with 15 bit wide program memory","pdk15")); + addOption(SDCC_CMD_OPT_PROCESSOR, QObject::tr("Optimization level (-Ox)"), groupName, true, true, false, "-m", sl); + + // C++ Language Standards + sl.clear(); + sl.append(QPair("ANSI C89/ISO C90","c89")); + sl.append(QPair("ISO C99","c99")); + sl.append(QPair("ISO C11","c11")); + sl.append(QPair("ISO C17","c17")); + sl.append(QPair("ISO C2x","c2x")); + sl.append(QPair("SDCC C89","sdcc89")); + sl.append(QPair("SDCC C99","sdcc99")); + sl.append(QPair("SDCC C11","sdcc11")); + sl.append(QPair("SDCC C17","sdcc17")); + sl.append(QPair("SDCC C2x","sdcc2x")); + addOption(SDCC_CMD_OPT_STD, QObject::tr("Language standard (-std)"), groupName, false, true, false, "-std-", sl); +} diff --git a/RedPandaIDE/compiler/compilerinfo.h b/RedPandaIDE/compiler/compilerinfo.h index 7827a2b4..a95ff781 100644 --- a/RedPandaIDE/compiler/compilerinfo.h +++ b/RedPandaIDE/compiler/compilerinfo.h @@ -8,6 +8,7 @@ #define COMPILER_CLANG "Clang" #define COMPILER_GCC "GCC" #define COMPILER_GCC_UTF8 "GCC_UTF8" +#define COMPILER_SDCC "SDCC" #define C_CMD_OPT_STD "c_cmd_opt_std" @@ -45,6 +46,9 @@ #define CC_CMD_OPT_STOP_AFTER_PREPROCESSING "cc_cmd_opt_stop_after_preprocessing" #define CC_CMD_OPT_USE_PIPE "cc_cmd_opt_use_pipe" +#define SDCC_CMD_OPT_PROCESSOR "sdcc_cmd_opt_processor" +#define SDCC_CMD_OPT_STD "sdcc_cmd_opt_std" + #define COMPILER_OPTION_ON "on" #define COMPILER_OPTION_OFF "" @@ -52,6 +56,7 @@ enum class CompilerType { GCC, GCC_UTF8, Clang, + SDCC, Unknown }; @@ -87,6 +92,8 @@ public: virtual bool supportConvertingCharset()=0; virtual bool forceUTF8InDebugger()=0; virtual bool forceUTF8InMakefile()=0; + virtual bool supportStaticLink()=0; + virtual bool supportSyntaxCheck(); protected: void addOption(const QString& key, const QString& name, @@ -112,12 +119,13 @@ using PCompilerInfoManager = std::shared_ptr; class CompilerInfoManager { public: CompilerInfoManager(); - static bool supportSyntaxCheck(CompilerType compilerType); static PCompilerInfo getInfo(CompilerType compilerType); static bool hasCompilerOption(CompilerType compilerType, const QString& optKey); static PCompilerOption getCompilerOption(CompilerType compilerType, const QString& optKey); static QList getCompilerOptions(CompilerType compilerType); static bool supportCovertingCharset(CompilerType compilerType); + static bool supportStaticLink(CompilerType compilerType); + static bool supportSyntaxCheck(CompilerType compilerType); static bool forceUTF8InDebugger(CompilerType compilerType); static PCompilerInfoManager getInstance(); static void addInfo(CompilerType compilerType, PCompilerInfo info); @@ -132,6 +140,7 @@ public: bool supportConvertingCharset() override; bool forceUTF8InDebugger() override; bool forceUTF8InMakefile() override; + bool supportStaticLink() override; }; class GCCCompilerInfo: public CompilerInfo{ @@ -140,6 +149,7 @@ public: bool supportConvertingCharset() override; bool forceUTF8InDebugger() override; bool forceUTF8InMakefile() override; + bool supportStaticLink() override; }; class GCCUTF8CompilerInfo: public CompilerInfo{ @@ -148,8 +158,20 @@ public: bool supportConvertingCharset() override; bool forceUTF8InDebugger() override; bool forceUTF8InMakefile() override; + bool supportStaticLink() override; +}; + +class SDCCCompilerInfo: public CompilerInfo{ +public: + SDCCCompilerInfo(); + bool supportConvertingCharset() override; + bool forceUTF8InDebugger() override; + bool forceUTF8InMakefile() override; + bool supportStaticLink() override; + bool supportSyntaxCheck() override; +protected: + void prepareCompilerOptions() override; }; - #endif // COMPILERINFO_H diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index ae79c467..b4608ae3 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -2948,14 +2948,10 @@ void Editor::initParser() if (pSettings->codeCompletion().enabled() && (isCFile(mFilename) || isHFile(mFilename))) { if (pSettings->codeCompletion().shareParser()) { - mParser = sharedParser(mUseCppSyntax?ParserLanguage::CPlusPlus:ParserLanguage::C); + mParser = sharedParser(calcParserLanguage()); } else { mParser = std::make_shared(); - if (mUseCppSyntax) { - mParser->setLanguage(ParserLanguage::CPlusPlus); - } else { - mParser->setLanguage(ParserLanguage::C); - } + mParser->setLanguage(calcParserLanguage()); mParser->setOnGetFileStream( std::bind( &EditorList::getContentFromOpenedEditor,pMainWindow->editorList(), @@ -2970,6 +2966,16 @@ void Editor::initParser() } } +ParserLanguage Editor::calcParserLanguage() +{ + if (!inProject() + && pSettings->compilerSets().defaultSet() + && pSettings->compilerSets().defaultSet()->compilerType()==CompilerType::SDCC) { + return ParserLanguage::SDCC; + } + return mUseCppSyntax?ParserLanguage::CPlusPlus:ParserLanguage::C; +} + Editor::QuoteStatus Editor::getQuoteStatus() { QuoteStatus Result = QuoteStatus::NotQuote; @@ -3110,8 +3116,8 @@ void Editor::reparse(bool resetParser) return; //qDebug()<<"reparse "<setEnabled(pSettings->codeCompletion().enabled()); - ParserLanguage language = mUseCppSyntax?ParserLanguage::CPlusPlus:ParserLanguage::C; if (!inProject()) { + ParserLanguage language = calcParserLanguage(); if (pSettings->codeCompletion().shareParser()) { if (language!=mParser->language()) { mParser->invalidateFile(mFilename); @@ -3461,12 +3467,21 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple keywords = syntaxer()->keywords(); } } else { - if (mUseCppSyntax) { + switch(calcParserLanguage()) { + case ParserLanguage::CPlusPlus: foreach (const QString& keyword, CppKeywords.keys()) { keywords.insert(keyword); } - } else { + break; + case ParserLanguage::C: keywords = CKeywords; + break; + case ParserLanguage::SDCC: + keywords = CKeywords; + foreach (const QString& keyword, SDCCKeywords.keys()) { + keywords.insert(keyword); + } + break; } if (pSettings->editor().enableCustomCTypeKeywords()) { foreach (const QString& keyword, pSettings->editor().customCTypeKeywords()) { @@ -5229,6 +5244,14 @@ void Editor::applySettings() set.insert(s); ((QSynedit::CppSyntaxer*)(syntaxer().get()))->setCustomTypeKeywords(set); } + } else if (!inProject() && pSettings->compilerSets().defaultSet() + && pSettings->compilerSets().defaultSet()->compilerType()==CompilerType::SDCC) { + if (syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::CPP) { + QSet set; + foreach(const QString& s, pSettings->editor().customCTypeKeywords()) + set.insert(s); + ((QSynedit::CppSyntaxer*)(syntaxer().get()))->setCustomTypeKeywords(set); + } } else { if (syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::CPP) { ((QSynedit::CppSyntaxer*)(syntaxer().get()))->setCustomTypeKeywords(QSet()); diff --git a/RedPandaIDE/editor.h b/RedPandaIDE/editor.h index 9a3623bf..e98a9534 100644 --- a/RedPandaIDE/editor.h +++ b/RedPandaIDE/editor.h @@ -262,6 +262,7 @@ private: bool handleCodeCompletion(QChar key); void initParser(); + ParserLanguage calcParserLanguage(); void undoSymbolCompletion(int pos); QuoteStatus getQuoteStatus(); diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index bad50f4d..1577d64c 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -1945,8 +1945,6 @@ void MainWindow::checkSyntaxInBack(Editor *e) return; if (mCompilerManager->compiling()) return; - if (!pSettings->compilerSets().defaultSet()) - return; if (mCheckSyntaxInBack) return; @@ -1962,8 +1960,15 @@ void MainWindow::checkSyntaxInBack(Editor *e) clearIssues(); CompileTarget target =getCompileTarget(); if (target ==CompileTarget::Project) { + int index = mProject->options().compilerSet; + Settings::PCompilerSet set = pSettings->compilerSets().getSet(index); + if (!set || !CompilerInfoManager::supportSyntaxCheck(set->compilerType())) + return; mCompilerManager->checkSyntax(e->filename(), e->fileEncoding(), e->text(), mProject); } else { + Settings::PCompilerSet set = pSettings->compilerSets().defaultSet(); + if (!set || !CompilerInfoManager::supportSyntaxCheck(set->compilerType())) + return; mCompilerManager->checkSyntax(e->filename(),e->fileEncoding(),e->text(), nullptr); } } @@ -3363,13 +3368,17 @@ void MainWindow::newEditor(const QString& suffix) { try { QString filename; - do { filename = QString("untitled%1").arg(getNewFileNumber()); if (suffix.isEmpty()) { - if (pSettings->editor().defaultFileCpp()) - filename+=".cpp"; - else + if (pSettings->editor().defaultFileCpp()) { + Settings::PCompilerSet compilerSet = pSettings->compilerSets().defaultSet(); + if (compilerSet && !compilerSet->canCompileCPP()) { + filename+=".c"; + } else { + filename+=".cpp"; + } + } else filename+=".c"; } else filename+= "." + suffix; diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index f15b0223..bf946982 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -2188,6 +2188,23 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType) isStatic); return; } else if (mTokenizer[mIndex + 1]->text == '(') { + if (mLanguage==ParserLanguage::SDCC && mTokenizer[mIndex]->text=="__at") { + if (!sName.isEmpty()) { + sType = sType+" "+sName; + sName = ""; + } + sType+=" __at"; + mIndex++; + int idx= mTokenizer[mIndex]->matchIndex; + if (idxtext; + } + } + mIndex=idx+1; + continue; + } + if (mIndex+2text == '*') { //foo(*blabla), it's a function pointer var handleVar(sType+" "+sName,isExtern,isStatic); @@ -2295,8 +2312,9 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType) isFriend = true; else if (s == "extern") isExtern = true; - if (!s.isEmpty() && !(s=="extern")) + if (!s.isEmpty() && !(s=="extern")) { sType = sType + ' '+ s; + } } mIndex++; } @@ -6401,7 +6419,18 @@ ParserLanguage CppParser::language() const void CppParser::setLanguage(ParserLanguage newLanguage) { - mLanguage = newLanguage; + if (mLanguage != newLanguage) { + mLanguage = newLanguage; + if (mLanguage == ParserLanguage::SDCC) { + mCppKeywords = CppKeywords; + mCppTypeKeywords = CppTypeKeywords; + mCppKeywords.insert(SDCCKeywords); + mCppTypeKeywords.unite(SDCCTypeKeywords); + } else { + mCppKeywords = CppKeywords; + mCppTypeKeywords = CppTypeKeywords; + } + } } diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index d67b6d2c..b3e2ac55 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -26,6 +26,8 @@ QStringList CppDirectives; QStringList JavadocTags; QMap CppKeywords; +QMap SDCCKeywords; +QSet SDCCTypeKeywords; QSet CppControlKeyWords; QSet CppTypeKeywords; QSet CKeywords; @@ -163,6 +165,27 @@ void initParser() CppKeywords.insert("void",KeywordType::None); CppKeywords.insert("wchar_t",KeywordType::None); + SDCCKeywords.insert("__sfr",KeywordType::None); + SDCCKeywords.insert("__sfr16",KeywordType::None); + SDCCKeywords.insert("__sfr32",KeywordType::None); + SDCCKeywords.insert("__sbit",KeywordType::None); + SDCCKeywords.insert("__bit",KeywordType::None); + SDCCKeywords.insert("__data",KeywordType::SkipItself); + SDCCKeywords.insert("__near",KeywordType::SkipItself); + SDCCKeywords.insert("__xdata",KeywordType::SkipItself); + SDCCKeywords.insert("__far",KeywordType::SkipItself); + SDCCKeywords.insert("__idata",KeywordType::SkipItself); + SDCCKeywords.insert("__pdata",KeywordType::SkipItself); + SDCCKeywords.insert("__code",KeywordType::SkipItself); + SDCCKeywords.insert("__banked",KeywordType::SkipItself); + SDCCKeywords.insert("__at",KeywordType::SkipNextParenthesis); + + SDCCTypeKeywords.insert("__sfr"); + SDCCTypeKeywords.insert("__sfr16"); + SDCCTypeKeywords.insert("__sfr32"); + SDCCTypeKeywords.insert("__sbit"); + SDCCTypeKeywords.insert("__bit"); + // type keywords CppTypeKeywords.insert("auto"); CppTypeKeywords.insert("bool"); diff --git a/RedPandaIDE/parser/parserutils.h b/RedPandaIDE/parser/parserutils.h index dce49cf1..87e685c8 100644 --- a/RedPandaIDE/parser/parserutils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -26,7 +26,8 @@ using GetFileStreamCallBack = std::function enum ParserLanguage { C, - CPlusPlus + CPlusPlus, + SDCC }; struct CodeSnippet { @@ -303,6 +304,8 @@ using PFileIncludes = std::shared_ptr; extern QStringList CppDirectives; extern QStringList JavadocTags; extern QMap CppKeywords; +extern QMap SDCCKeywords; +extern QSet SDCCTypeKeywords; extern QSet CppControlKeyWords; extern QSet CKeywords; extern QSet CppTypeKeywords; diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index 057a66eb..77ed35ad 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef Q_OS_LINUX #include #endif @@ -1701,7 +1702,7 @@ Settings::CompilerSet::CompilerSet(const QString& compilerFolder, const QString& setProperties(compilerFolder,c_prog); //manually set the directories - setDirectories(compilerFolder, mCompilerType); + setDirectories(compilerFolder); setExecutables(); @@ -2008,7 +2009,7 @@ QStringList &Settings::CompilerSet::defaultCIncludeDirs() { if (!mFullLoaded && !binDirs().isEmpty()) { mFullLoaded=true; - setDirectories(binDirs()[0],mCompilerType); + setDirectories(binDirs()[0]); } return mDefaultCIncludeDirs; } @@ -2017,7 +2018,7 @@ QStringList &Settings::CompilerSet::defaultCppIncludeDirs() { if (!mFullLoaded && !binDirs().isEmpty()) { mFullLoaded=true; - setDirectories(binDirs()[0],mCompilerType); + setDirectories(binDirs()[0]); } return mDefaultCppIncludeDirs; } @@ -2026,7 +2027,7 @@ QStringList &Settings::CompilerSet::defaultLibDirs() { if (!mFullLoaded && !binDirs().isEmpty()) { mFullLoaded=true; - setDirectories(binDirs()[0],mCompilerType); + setDirectories(binDirs()[0]); } return mLibDirs; } @@ -2153,6 +2154,15 @@ static void addExistingDirectory(QStringList& dirs, const QString& directory) { } void Settings::CompilerSet::setProperties(const QString& binDir, const QString& c_prog) +{ + if (c_prog == SDCC_PROGRAM) { + setSDCCProperties(binDir,c_prog); + } else { + setGCCProperties(binDir,c_prog); + } +} + +void Settings::CompilerSet::setGCCProperties(const QString& binDir, const QString& c_prog) { // We have tested before the call // if (!fileExists(c_prog)) @@ -2268,10 +2278,6 @@ void Settings::CompilerSet::setProperties(const QString& binDir, const QString& // Add the default directories addExistingDirectory(mBinDirs, includeTrailingPathDelimiter(folder) + "bin"); -// addExistingDirectory(mDefaultLibDirs, includeTrailingPathDelimiter(folder) + "lib"); -// addExistingDirectory(mDefaultCIncludeDirs, includeTrailingPathDelimiter(folder) + "include"); -// addExistingDirectory(mDefaultCppIncludeDirs, includeTrailingPathDelimiter(folder) + "include"); - if (!mDumpMachine.isEmpty()) { //mingw-w64 bin folder addExistingDirectory(mBinDirs, @@ -2281,6 +2287,39 @@ void Settings::CompilerSet::setProperties(const QString& binDir, const QString& } } +void Settings::CompilerSet::setSDCCProperties(const QString& binDir, const QString& c_prog) +{ + // We have tested before the call +// if (!fileExists(c_prog)) +// return; + // Obtain version number and compiler distro etc + QStringList arguments; + arguments.append("-v"); + QByteArray output = getCompilerOutput(binDir, c_prog,arguments); + + if (!output.startsWith("SDCC")) + return; + + //Target + int delimPos = 0; + while (delimPos=32)) + delimPos++; + QString triplet = output.mid(0,delimPos); + + qDebug()<0 && delimPos2>delimPos1 ) { + delimPos1 += targetStr.length(); + QList lines = output.mid(delimPos1, delimPos2-delimPos1).split('\n'); + for (QByteArray& line:lines) { + QByteArray trimmedLine = line.trimmed(); + if (!trimmedLine.isEmpty()) { + addExistingDirectory(mBinDirs,trimmedLine); + } + } + } + + targetStr = QByteArray("includedir:"); + delimPos1 = output.indexOf(targetStr); + delimPos2 = output.indexOf("libdir:"); + if (delimPos1 >0 && delimPos2>delimPos1 ) { + delimPos1 += targetStr.length(); + QList lines = output.mid(delimPos1, delimPos2-delimPos1).split('\n'); + for (QByteArray& line:lines) { + QByteArray trimmedLine = line.trimmed(); + if (!trimmedLine.isEmpty()) { + addExistingDirectory(mDefaultCIncludeDirs,trimmedLine); + } + } + } + + targetStr = QByteArray("libdir:"); + delimPos1 = output.indexOf(targetStr); + delimPos2 = output.indexOf("libpath:"); + if (delimPos1 >0 && delimPos2>delimPos1 ) { + delimPos1 += targetStr.length(); + QList lines = output.mid(delimPos1, delimPos2-delimPos1).split('\n'); + for (QByteArray& line:lines) { + QByteArray trimmedLine = line.trimmed(); + if (!trimmedLine.isEmpty()) { + addExistingDirectory(mDefaultLibDirs,trimmedLine); + } + } + } + +} + int Settings::CompilerSet::mainVersion() const { int i = mVersion.indexOf('.'); @@ -2528,8 +2641,13 @@ void Settings::CompilerSet::setUserInput() { mUseCustomCompileParams = false; mUseCustomLinkParams = false; - mAutoAddCharsetParams = true; - mStaticLink = true; + if (mCompilerType==CompilerType::SDCC) { + mAutoAddCharsetParams = false; + mStaticLink = false; + } else { + mAutoAddCharsetParams = true; + mStaticLink = true; + } } @@ -2812,45 +2930,44 @@ bool Settings::CompilerSets::addSets(const QString &folder, const QString& c_pro PCompilerSet baseSet = addSet(folder,c_prog); if (!baseSet || baseSet->name().isEmpty()) return false; - QString baseName = baseSet->name(); - QString platformName; - if (isTarget64Bit(baseSet->target())) { - if (baseName.startsWith("TDM-GCC ")) { - PCompilerSet set= addSet(baseSet); - platformName = "32-bit"; - set->setName(baseName + " " + platformName + " Release"); - set64_32Options(set); - setReleaseOptions(set); - - set = addSet(baseSet); - set->setName(baseName + " " + platformName + " Debug"); - set64_32Options(set); - setDebugOptions(set); - } - platformName = "64-bit"; + if (c_prog == SDCC_PROGRAM) { + //sdcc do nothing } else { - platformName = "32-bit"; - } + QString baseName = baseSet->name(); + QString platformName; + if (isTarget64Bit(baseSet->target())) { + if (baseName.startsWith("TDM-GCC ")) { + PCompilerSet set= addSet(baseSet); + platformName = "32-bit"; + set->setName(baseName + " " + platformName + " Release"); + set64_32Options(set); + setReleaseOptions(set); + + set = addSet(baseSet); + set->setName(baseName + " " + platformName + " Debug"); + set64_32Options(set); + setDebugOptions(set); + } + platformName = "64-bit"; + } else { + platformName = "32-bit"; + } - PCompilerSet debugSet = addSet(baseSet); - debugSet->setName(baseName + " " + platformName + " Debug"); - setDebugOptions(debugSet); + PCompilerSet debugSet = addSet(baseSet); + debugSet->setName(baseName + " " + platformName + " Debug"); + setDebugOptions(debugSet); - // Enable ASan compiler set if it is supported and gdb works with ASan. + // Enable ASan compiler set if it is supported and gdb works with ASan. #ifdef Q_OS_LINUX - PCompilerSet debugAsanSet = addSet(baseSet); - debugAsanSet->setName(baseName + " " + platformName + " Debug with ASan"); - setDebugOptions(debugAsanSet, true); + PCompilerSet debugAsanSet = addSet(baseSet); + debugAsanSet->setName(baseName + " " + platformName + " Debug with ASan"); + setDebugOptions(debugAsanSet, true); #endif - baseSet->setName(baseName + " " + platformName + " Release"); - setReleaseOptions(baseSet); - -// baseSet = addSet(folder); -// baseSet->setName(baseName + " " + platformName + " Profiling"); -// baseSet->setCompilerSetType(CompilerSetType::CST_PROFILING); -// setProfileOptions(baseSet); + baseSet->setName(baseName + " " + platformName + " Release"); + setReleaseOptions(baseSet); + } #ifdef Q_OS_LINUX # if defined(__x86_64__) || __SIZEOF_POINTER__ == 4 @@ -2870,17 +2987,19 @@ bool Settings::CompilerSets::addSets(const QString &folder) { if (!directoryExists(folder)) return false; - if (!fileExists(folder, GCC_PROGRAM) && !fileExists(folder, CLANG_PROGRAM)) { - return false; - } if (fileExists(folder, GCC_PROGRAM)) { addSets(folder,GCC_PROGRAM); + return true; } if (fileExists(folder, CLANG_PROGRAM)) { addSets(folder,CLANG_PROGRAM); + return true; } - return true; - + if (fileExists(folder, SDCC_PROGRAM)) { + addSets(folder,SDCC_PROGRAM); + return true; + } + return false; } void Settings::CompilerSets::clearSets() @@ -3214,6 +3333,8 @@ Settings::PCompilerSet Settings::CompilerSets::loadSet(int index) pSet->setCompilerType(CompilerType::GCC); } else if (temp==COMPILER_GCC_UTF8) { pSet->setCompilerType(CompilerType::GCC_UTF8); + } else if (temp==COMPILER_SDCC) { + pSet->setCompilerType(CompilerType::SDCC); } else { pSet->setCompilerType((CompilerType)mSettings->mSettings.value("CompilerType").toInt()); } diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h index c31b0617..c1028795 100644 --- a/RedPandaIDE/settings.h +++ b/RedPandaIDE/settings.h @@ -1441,7 +1441,11 @@ public: bool isCompilerInfoUsingUTF8() const; private: - void setDirectories(const QString& binDir, CompilerType mCompilerType); + void setGCCProperties(const QString& binDir, const QString& c_prog); + void setSDCCProperties(const QString& binDir, const QString& c_prog); + void setDirectories(const QString& binDir); + void setGCCDirectories(const QString& binDir); + void setSDCCDirectories(const QString& binDir); //load hard defines void setExecutables(); void setUserInput(); diff --git a/RedPandaIDE/settingsdialog/compilersetoptionwidget.cpp b/RedPandaIDE/settingsdialog/compilersetoptionwidget.cpp index 4a24db38..26e2df84 100644 --- a/RedPandaIDE/settingsdialog/compilersetoptionwidget.cpp +++ b/RedPandaIDE/settingsdialog/compilersetoptionwidget.cpp @@ -74,12 +74,17 @@ void CompilerSetOptionWidget::init() static void loadCompilerSetSettings(Settings::PCompilerSet pSet, Ui::CompilerSetOptionWidget* ui) { - ui->chkAutoAddCharset->setEnabled(pSet->compilerType() != CompilerType::Clang); - ui->chkAutoAddCharset->setVisible(pSet->compilerType() != CompilerType::Clang); - ui->cbEncoding->setEnabled(pSet->compilerType() != CompilerType::Clang); - ui->cbEncoding->setVisible(pSet->compilerType() != CompilerType::Clang); - ui->cbEncodingDetails->setEnabled(pSet->compilerType() != CompilerType::Clang); - ui->cbEncodingDetails->setVisible(pSet->compilerType() != CompilerType::Clang); + bool supportCharset = CompilerInfoManager::supportCovertingCharset(pSet->compilerType()); + ui->chkAutoAddCharset->setEnabled(supportCharset); + ui->cbEncoding->setEnabled(supportCharset); + ui->cbEncodingDetails->setEnabled(supportCharset); + ui->panelCharset->setVisible(supportCharset); + ui->chkAutoAddCharset->setEnabled(supportCharset); + ui->chkAutoAddCharset->setVisible(supportCharset); + + bool supportStaticLink = CompilerInfoManager::supportStaticLink(pSet->compilerType()); + ui->chkStaticLink->setEnabled(supportStaticLink); + ui->chkStaticLink->setVisible(supportStaticLink); ui->chkUseCustomCompilerParams->setChecked(pSet->useCustomCompileParams()); ui->txtCustomCompileParams->setPlainText(pSet->customCompileParams()); diff --git a/RedPandaIDE/settingsdialog/compilersetoptionwidget.ui b/RedPandaIDE/settingsdialog/compilersetoptionwidget.ui index 6f993544..ec2436d6 100644 --- a/RedPandaIDE/settingsdialog/compilersetoptionwidget.ui +++ b/RedPandaIDE/settingsdialog/compilersetoptionwidget.ui @@ -121,7 +121,7 @@ - + 0 diff --git a/RedPandaIDE/systemconsts.h b/RedPandaIDE/systemconsts.h index bd2fcb85..e80e88a7 100644 --- a/RedPandaIDE/systemconsts.h +++ b/RedPandaIDE/systemconsts.h @@ -37,6 +37,7 @@ #define CLANG_CPP_PROGRAM "clang++.exe" #define LLDB_MI_PROGRAM "lldb-mi.exe" #define LLDB_SERVER_PROGRAM "lldb-server.exe" +#define SDCC_PROGRAM "sdcc.exe" #elif defined(Q_OS_LINUX) #define CONSOLE_PAUSER "consolepauser" #define ASSEMBLER "nasm" @@ -55,6 +56,7 @@ #define CLANG_CPP_PROGRAM "clang++" #define LLDB_MI_PROGRAM "lldb-mi" #define LLDB_SERVER_PROGRAM "lldb-server" +#define SDCC_PROGRAM "sdcc" #elif defined(Q_OS_MACOS) #define CONSOLE_PAUSER "consolepauser" #define ASSEMBLER "nasm" @@ -72,6 +74,7 @@ #define CLANG_CPP_PROGRAM "clang++" #define LLDB_MI_PROGRAM "lldb-mi" #define LLDB_SERVER_PROGRAM "lldb-server" +#define SDCC_PROGRAM "sdcc" #else #error "Only support windows, Linux and MacOS now!" #endif