diff options
Diffstat (limited to 'src/plugins/cpptools')
21 files changed, 435 insertions, 3250 deletions
diff --git a/src/plugins/cpptools/cppclassesfilter.cpp b/src/plugins/cpptools/cppclassesfilter.cpp index 3d8da9a738..6aa6734fca 100644 --- a/src/plugins/cpptools/cppclassesfilter.cpp +++ b/src/plugins/cpptools/cppclassesfilter.cpp @@ -42,6 +42,7 @@ CppClassesFilter::CppClassesFilter(CppModelManager *manager, Core::EditorManager setIncludedByDefault(false); search.setSymbolsToSearchFor(SearchSymbols::Classes); + search.setSeparateScope(true); } CppClassesFilter::~CppClassesFilter() diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp index 7568d2c887..d24f5a5f81 100644 --- a/src/plugins/cpptools/cppcodecompletion.cpp +++ b/src/plugins/cpptools/cppcodecompletion.cpp @@ -699,7 +699,9 @@ void CppCodeCompletion::addMacros(const LookupContext &context) continue; processed.insert(fn); if (Document::Ptr doc = context.document(fn)) { - macroNames += doc->macroNames(); + foreach (const Macro macro, doc->definedMacros()) { + macroNames.insert(macro.name); + } todo += doc->includedFiles(); } } @@ -1025,6 +1027,10 @@ bool CppCodeCompletion::partiallyComplete(const QList<TextEditor::CompletionItem void CppCodeCompletion::cleanup() { m_completions.clear(); + + // Set empty map in order to avoid referencing old versions of the documents + // until the next completion + typeOfExpression.setDocuments(QMap<QString, Document::Ptr>()); } int CppCodeCompletion::findStartOfName(const TextEditor::ITextEditor *editor) diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index b3f9fb604c..a165614a59 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -31,8 +31,7 @@ ** ***************************************************************************/ -#define _SCL_SECURE_NO_WARNINGS 1 -#include "pp.h" +#include <cplusplus/pp.h> #include "cppmodelmanager.h" #include "cpphoverhandler.h" @@ -66,14 +65,14 @@ #include <Token.h> #include <QPlainTextEdit> +#include <QMutexLocker> #include <QTime> #include <QDebug> +using namespace CppTools; +using namespace CppTools::Internal; using namespace CPlusPlus; -namespace CppTools { -namespace Internal { - static const char pp_configuration_file[] = "<configuration>"; static const char pp_configuration[] = @@ -105,299 +104,322 @@ static const char pp_configuration[] = "#define __declspec(a)\n" "#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method\n"; -class CppPreprocessor: public rpp::Client +namespace CppTools { +namespace Internal { + +class CppPreprocessor: public CPlusPlus::Client { public: - CppPreprocessor(QPointer<CppModelManager> modelManager) - : m_modelManager(modelManager), - m_documents(modelManager->documents()), - m_proc(this, env) - { } + CppPreprocessor(QPointer<CppModelManager> modelManager); + + void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy); + void setIncludePaths(const QStringList &includePaths); + void setFrameworkPaths(const QStringList &frameworkPaths); + void setProjectFiles(const QStringList &files); + void run(QString &fileName); + void operator()(QString &fileName); + +protected: + CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc); + + bool includeFile(const QString &absoluteFilePath, QByteArray *result); + QByteArray tryIncludeFile(QString &fileName, IncludeType type); + + void mergeEnvironment(CPlusPlus::Document::Ptr doc); + void mergeEnvironment(CPlusPlus::Document::Ptr doc, QSet<QString> *processed); + + virtual void macroAdded(const Macro ¯o); + virtual void startExpandingMacro(unsigned offset, + const Macro ¯o, + const QByteArray &originalText); + virtual void stopExpandingMacro(unsigned offset, const Macro ¯o); + virtual void startSkippingBlocks(unsigned offset); + virtual void stopSkippingBlocks(unsigned offset); + virtual void sourceNeeded(QString &fileName, IncludeType type); + +private: + QPointer<CppModelManager> m_modelManager; + CppModelManager::DocumentTable m_documents; + Environment env; + pp m_proc; + QStringList m_includePaths; + QStringList m_systemIncludePaths; + QMap<QString, QByteArray> m_workingCopy; + QStringList m_projectFiles; + QStringList m_frameworkPaths; + QSet<QString> m_included; + CPlusPlus::Document::Ptr m_currentDoc; +}; - void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy) - { m_workingCopy = workingCopy; } +} // namespace Internal +} // namespace CppTools - void setIncludePaths(const QStringList &includePaths) - { m_includePaths = includePaths; } +CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager) + : m_modelManager(modelManager), + m_documents(modelManager->documents()), + m_proc(this, env) +{ } - void setFrameworkPaths(const QStringList &frameworkPaths) - { m_frameworkPaths = frameworkPaths; } +void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy) +{ m_workingCopy = workingCopy; } - void addIncludePath(const QString &path) - { m_includePaths.append(path); } +void CppPreprocessor::setIncludePaths(const QStringList &includePaths) +{ m_includePaths = includePaths; } - void setProjectFiles(const QStringList &files) - { m_projectFiles = files; } +void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths) +{ m_frameworkPaths = frameworkPaths; } - void run(QString &fileName) - { sourceNeeded(fileName, IncludeGlobal); } +void CppPreprocessor::setProjectFiles(const QStringList &files) +{ m_projectFiles = files; } - void operator()(QString &fileName) - { run(fileName); } +void CppPreprocessor::run(QString &fileName) +{ sourceNeeded(fileName, IncludeGlobal); } -protected: - bool includeFile(const QString &absoluteFilePath, QByteArray *result) - { - if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) { - return true; - } +void CppPreprocessor::operator()(QString &fileName) +{ run(fileName); } - if (m_workingCopy.contains(absoluteFilePath)) { - m_included.insert(absoluteFilePath); - *result = m_workingCopy.value(absoluteFilePath); - return true; - } +bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QByteArray *result) +{ + if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) { + return true; + } - QFileInfo fileInfo(absoluteFilePath); - if (! fileInfo.isFile()) - return false; - - QFile file(absoluteFilePath); - if (file.open(QFile::ReadOnly)) { - m_included.insert(absoluteFilePath); - QTextStream stream(&file); - const QString contents = stream.readAll(); - *result = contents.toUtf8(); - file.close(); - return true; - } + if (m_workingCopy.contains(absoluteFilePath)) { + m_included.insert(absoluteFilePath); + *result = m_workingCopy.value(absoluteFilePath); + return true; + } + QFileInfo fileInfo(absoluteFilePath); + if (! fileInfo.isFile()) return false; + + QFile file(absoluteFilePath); + if (file.open(QFile::ReadOnly)) { + m_included.insert(absoluteFilePath); + QTextStream stream(&file); + const QString contents = stream.readAll(); + *result = contents.toUtf8(); + file.close(); + return true; } - QByteArray tryIncludeFile(QString &fileName, IncludeType type) - { - QFileInfo fileInfo(fileName); - if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) { - QByteArray contents; - includeFile(fileName, &contents); + return false; +} + +QByteArray CppPreprocessor::tryIncludeFile(QString &fileName, IncludeType type) +{ + QFileInfo fileInfo(fileName); + if (fileName == QLatin1String(pp_configuration_file) || fileInfo.isAbsolute()) { + QByteArray contents; + includeFile(fileName, &contents); + return contents; + } + + if (type == IncludeLocal && m_currentDoc) { + QFileInfo currentFileInfo(m_currentDoc->fileName()); + QString path = currentFileInfo.absolutePath(); + path += QLatin1Char('/'); + path += fileName; + path = QDir::cleanPath(path); + QByteArray contents; + if (includeFile(path, &contents)) { + fileName = path; return contents; } + } - if (type == IncludeLocal && m_currentDoc) { - QFileInfo currentFileInfo(m_currentDoc->fileName()); - QString path = currentFileInfo.absolutePath(); - path += QLatin1Char('/'); - path += fileName; - path = QDir::cleanPath(path); - QByteArray contents; - if (includeFile(path, &contents)) { - fileName = path; - return contents; - } + foreach (const QString &includePath, m_includePaths) { + QString path = includePath; + path += QLatin1Char('/'); + path += fileName; + path = QDir::cleanPath(path); + QByteArray contents; + if (includeFile(path, &contents)) { + fileName = path; + return contents; } + } - foreach (const QString &includePath, m_includePaths) { - QString path = includePath; - path += QLatin1Char('/'); - path += fileName; - path = QDir::cleanPath(path); - QByteArray contents; - if (includeFile(path, &contents)) { - fileName = path; - return contents; - } + // look in the system include paths + foreach (const QString &includePath, m_systemIncludePaths) { + QString path = includePath; + path += QLatin1Char('/'); + path += fileName; + path = QDir::cleanPath(path); + QByteArray contents; + if (includeFile(path, &contents)) { + fileName = path; + return contents; } + } - // look in the system include paths - foreach (const QString &includePath, m_systemIncludePaths) { - QString path = includePath; + int index = fileName.indexOf(QLatin1Char('/')); + if (index != -1) { + QString frameworkName = fileName.left(index); + QString name = fileName.mid(index + 1); + + foreach (const QString &frameworkPath, m_frameworkPaths) { + QString path = frameworkPath; path += QLatin1Char('/'); - path += fileName; - path = QDir::cleanPath(path); + path += frameworkName; + path += QLatin1String(".framework/Headers/"); + path += name; QByteArray contents; if (includeFile(path, &contents)) { fileName = path; return contents; } } + } - int index = fileName.indexOf(QLatin1Char('/')); - if (index != -1) { - QString frameworkName = fileName.left(index); - QString name = fileName.mid(index + 1); - - foreach (const QString &frameworkPath, m_frameworkPaths) { - QString path = frameworkPath; - path += QLatin1Char('/'); - path += frameworkName; - path += QLatin1String(".framework/Headers/"); - path += name; - QByteArray contents; - if (includeFile(path, &contents)) { - fileName = path; - return contents; - } - } - } - - QString path = fileName; - if (path.at(0) != QLatin1Char('/')) - path.prepend(QLatin1Char('/')); + QString path = fileName; + if (path.at(0) != QLatin1Char('/')) + path.prepend(QLatin1Char('/')); - foreach (const QString &projectFile, m_projectFiles) { - if (projectFile.endsWith(path)) { - fileName = projectFile; - QByteArray contents; - includeFile(fileName, &contents); - return contents; - } + foreach (const QString &projectFile, m_projectFiles) { + if (projectFile.endsWith(path)) { + fileName = projectFile; + QByteArray contents; + includeFile(fileName, &contents); + return contents; } - - //qDebug() << "**** file" << fileName << "not found!"; - return QByteArray(); } - virtual void macroAdded(const QByteArray ¯oName, const QByteArray ¯oText) - { - if (! m_currentDoc) - return; + //qDebug() << "**** file" << fileName << "not found!"; + return QByteArray(); +} - m_currentDoc->appendMacro(macroName, macroText); - } +void CppPreprocessor::macroAdded(const Macro ¯o) +{ + if (! m_currentDoc) + return; - virtual void startExpandingMacro(unsigned offset, - const rpp::Macro &, - const QByteArray &originalText) - { - if (! m_currentDoc) - return; - - //qDebug() << "start expanding:" << macro.name << "text:" << originalText; - m_currentDoc->addMacroUse(offset, originalText.length()); - } + m_currentDoc->appendMacro(macro); +} - virtual void stopExpandingMacro(unsigned, const rpp::Macro &) - { - if (! m_currentDoc) - return; +void CppPreprocessor::startExpandingMacro(unsigned offset, + const Macro &, + const QByteArray &originalText) +{ + if (! m_currentDoc) + return; - //qDebug() << "stop expanding:" << macro.name; - } + //qDebug() << "start expanding:" << macro.name << "text:" << originalText; + m_currentDoc->addMacroUse(offset, originalText.length()); +} - void mergeEnvironment(Document::Ptr doc) - { - QSet<QString> processed; - mergeEnvironment(doc, &processed); - } +void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &) +{ + if (! m_currentDoc) + return; - void mergeEnvironment(Document::Ptr doc, QSet<QString> *processed) - { - if (! doc) - return; + //qDebug() << "stop expanding:" << macro.name; +} - const QString fn = doc->fileName(); +void CppPreprocessor::mergeEnvironment(Document::Ptr doc) +{ + QSet<QString> processed; + mergeEnvironment(doc, &processed); +} - if (processed->contains(fn)) - return; +void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *processed) +{ + if (! doc) + return; - processed->insert(fn); + const QString fn = doc->fileName(); - foreach (QString includedFile, doc->includedFiles()) - mergeEnvironment(m_documents.value(includedFile), processed); + if (processed->contains(fn)) + return; - const QByteArray macros = doc->definedMacros(); - QByteArray localFileName = doc->fileName().toUtf8(); + processed->insert(fn); - QByteArray dummy; - m_proc(localFileName, macros, &dummy); + foreach (QString includedFile, doc->includedFiles()) { + mergeEnvironment(m_documents.value(includedFile), processed); } - virtual void startSkippingBlocks(unsigned offset) - { - //qDebug() << "start skipping blocks:" << offset; - if (m_currentDoc) - m_currentDoc->startSkippingBlocks(offset); + foreach (const Macro macro, doc->definedMacros()) { + env.bind(macro); } +} - virtual void stopSkippingBlocks(unsigned offset) - { - //qDebug() << "stop skipping blocks:" << offset; - if (m_currentDoc) - m_currentDoc->stopSkippingBlocks(offset); - } +void CppPreprocessor::startSkippingBlocks(unsigned offset) +{ + //qDebug() << "start skipping blocks:" << offset; + if (m_currentDoc) + m_currentDoc->startSkippingBlocks(offset); +} - virtual void sourceNeeded(QString &fileName, IncludeType type) - { - if (fileName.isEmpty()) - return; - - QByteArray contents = tryIncludeFile(fileName, type); - - if (m_currentDoc) { - m_currentDoc->addIncludeFile(fileName); - if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) { - QString msg; - msg += fileName; - msg += QLatin1String(": No such file or directory"); - Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning, - m_currentDoc->fileName(), - env.currentLine, /*column = */ 0, - msg); - m_currentDoc->addDiagnosticMessage(d); - //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line; - } +void CppPreprocessor::stopSkippingBlocks(unsigned offset) +{ + //qDebug() << "stop skipping blocks:" << offset; + if (m_currentDoc) + m_currentDoc->stopSkippingBlocks(offset); +} + +void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type) +{ + if (fileName.isEmpty()) + return; + + QByteArray contents = tryIncludeFile(fileName, type); + + if (m_currentDoc) { + m_currentDoc->addIncludeFile(fileName); + if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) { + QString msg; + msg += fileName; + msg += QLatin1String(": No such file or directory"); + Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning, + m_currentDoc->fileName(), + env.currentLine, /*column = */ 0, + msg); + m_currentDoc->addDiagnosticMessage(d); + //qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line; } + } - if (! contents.isEmpty()) { - Document::Ptr cachedDoc = m_documents.value(fileName); - if (cachedDoc && m_currentDoc) { - mergeEnvironment(cachedDoc); - } else { - Document::Ptr previousDoc = switchDocument(Document::create(fileName)); + if (! contents.isEmpty()) { + Document::Ptr cachedDoc = m_documents.value(fileName); + if (cachedDoc && m_currentDoc) { + mergeEnvironment(cachedDoc); + } else { + Document::Ptr previousDoc = switchDocument(Document::create(fileName)); - const QByteArray previousFile = env.current_file; - const unsigned previousLine = env.currentLine; + const QByteArray previousFile = env.current_file; + const unsigned previousLine = env.currentLine; - env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(), - m_currentDoc->translationUnit()->fileNameLength()); + env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(), + m_currentDoc->translationUnit()->fileNameLength()); - QByteArray preprocessedCode; - m_proc(contents, &preprocessedCode); - //qDebug() << preprocessedCode; + QByteArray preprocessedCode; + m_proc(contents, &preprocessedCode); + //qDebug() << preprocessedCode; - env.current_file = previousFile; - env.currentLine = previousLine; + env.current_file = previousFile; + env.currentLine = previousLine; - m_currentDoc->setSource(preprocessedCode); - m_currentDoc->parse(); - m_currentDoc->check(); - m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream. + m_currentDoc->setSource(preprocessedCode); + m_currentDoc->parse(); + m_currentDoc->check(); + m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream. - if (m_modelManager) - m_modelManager->emitDocumentUpdated(m_currentDoc); - (void) switchDocument(previousDoc); - } + if (m_modelManager) + m_modelManager->emitDocumentUpdated(m_currentDoc); + (void) switchDocument(previousDoc); } } +} - Document::Ptr switchDocument(Document::Ptr doc) - { - Document::Ptr previousDoc = m_currentDoc; - m_currentDoc = doc; - return previousDoc; - } - -private: - QPointer<CppModelManager> m_modelManager; - CppModelManager::DocumentTable m_documents; - rpp::Environment env; - rpp::pp m_proc; - QStringList m_includePaths; - QStringList m_systemIncludePaths; - QMap<QString, QByteArray> m_workingCopy; - QStringList m_projectFiles; - QStringList m_frameworkPaths; - QSet<QString> m_included; - Document::Ptr m_currentDoc; -}; - -} // namespace Internal -} // namespace CppTools +Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc) +{ + Document::Ptr previousDoc = m_currentDoc; + m_currentDoc = doc; + return previousDoc; +} -using namespace CppTools; -using namespace CppTools::Internal; /*! \class CppTools::CppModelManager @@ -450,13 +472,26 @@ CppModelManager::CppModelManager(QObject *parent) : CppModelManager::~CppModelManager() { } -Document::Ptr CppModelManager::document(const QString &fileName) +Document::Ptr CppModelManager::document(const QString &fileName) const { return m_documents.value(fileName); } -CppModelManager::DocumentTable CppModelManager::documents() +CppModelManager::DocumentTable CppModelManager::documents() const { return m_documents; } -QStringList CppModelManager::updateProjectFiles() const +void CppModelManager::ensureUpdated() +{ + QMutexLocker locker(&mutex); + if (! m_dirty) + return; + + m_projectFiles = internalProjectFiles(); + m_includePaths = internalIncludePaths(); + m_frameworkPaths = internalFrameworkPaths(); + m_definedMacros = internalDefinedMacros(); + m_dirty = false; +} + +QStringList CppModelManager::internalProjectFiles() const { QStringList files; QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); @@ -465,10 +500,11 @@ QStringList CppModelManager::updateProjectFiles() const ProjectInfo pinfo = it.value(); files += pinfo.sourceFiles; } + files.removeDuplicates(); return files; } -QStringList CppModelManager::updateIncludePaths() const +QStringList CppModelManager::internalIncludePaths() const { QStringList includePaths; QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); @@ -477,10 +513,11 @@ QStringList CppModelManager::updateIncludePaths() const ProjectInfo pinfo = it.value(); includePaths += pinfo.includePaths; } + includePaths.removeDuplicates(); return includePaths; } -QStringList CppModelManager::updateFrameworkPaths() const +QStringList CppModelManager::internalFrameworkPaths() const { QStringList frameworkPaths; QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); @@ -489,10 +526,11 @@ QStringList CppModelManager::updateFrameworkPaths() const ProjectInfo pinfo = it.value(); frameworkPaths += pinfo.frameworkPaths; } + frameworkPaths.removeDuplicates(); return frameworkPaths; } -QByteArray CppModelManager::updateDefinedMacros() const +QByteArray CppModelManager::internalDefinedMacros() const { QByteArray macros; QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); @@ -527,8 +565,30 @@ QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList() void CppModelManager::updateSourceFiles(const QStringList &sourceFiles) { (void) refreshSourceFiles(sourceFiles); } -CppModelManager::ProjectInfo *CppModelManager::projectInfo(ProjectExplorer::Project *project) -{ return &m_projects[project]; } +QList<CppModelManager::ProjectInfo> CppModelManager::projectInfos() const +{ + QMutexLocker locker(&mutex); + + return m_projects.values(); +} + +CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Project *project) const +{ + QMutexLocker locker(&mutex); + + return m_projects.value(project, ProjectInfo(project)); +} + +void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) +{ + QMutexLocker locker(&mutex); + + if (! pinfo.isValid()) + return; + + m_projects.insert(pinfo.project, pinfo); + m_dirty = true; +} QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles) { @@ -683,7 +743,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc) sel.cursor = c; selections.append(sel); } - ed->setExtraExtraSelections(selections); + ed->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection, selections); break; } } @@ -691,13 +751,18 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc) void CppModelManager::onProjectAdded(ProjectExplorer::Project *) { + QMutexLocker locker(&mutex); m_dirty = true; } void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) { - m_dirty = true; - m_projects.remove(project); + do { + QMutexLocker locker(&mutex); + m_dirty = true; + m_projects.remove(project); + } while (0); + GC(); } @@ -705,8 +770,15 @@ void CppModelManager::onSessionUnloaded() { if (m_core->progressManager()) { m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX); - m_dirty = true; } + + do { + QMutexLocker locker(&mutex); + m_projects.clear(); + m_dirty = true; + } while (0); + + GC(); } void CppModelManager::parse(QFutureInterface<void> &future, diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index a91a414e48..3b2f4e1999 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -40,6 +40,7 @@ #include <QMap> #include <QFutureInterface> +#include <QMutex> namespace Core { class ICore; @@ -70,9 +71,13 @@ public: virtual ~CppModelManager(); virtual void updateSourceFiles(const QStringList &sourceFiles); - virtual ProjectInfo *projectInfo(ProjectExplorer::Project *project); - virtual CPlusPlus::Document::Ptr document(const QString &fileName); - virtual DocumentTable documents(); + + virtual QList<ProjectInfo> projectInfos() const; + virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const; + virtual void updateProjectInfo(const ProjectInfo &pinfo); + + virtual CPlusPlus::Document::Ptr document(const QString &fileName) const; + virtual DocumentTable documents() const; virtual void GC(); QFuture<void> refreshSourceFiles(const QStringList &sourceFiles); @@ -127,21 +132,11 @@ private: return m_definedMacros; } - QStringList updateProjectFiles() const; - QStringList updateIncludePaths() const; - QStringList updateFrameworkPaths() const; - QByteArray updateDefinedMacros() const; - - void ensureUpdated() { - if (! m_dirty) - return; - - m_projectFiles = updateProjectFiles(); - m_includePaths = updateIncludePaths(); - m_frameworkPaths = updateFrameworkPaths(); - m_definedMacros = updateDefinedMacros(); - m_dirty = false; - } + void ensureUpdated(); + QStringList internalProjectFiles() const; + QStringList internalIncludePaths() const; + QStringList internalFrameworkPaths() const; + QByteArray internalDefinedMacros() const; static void parse(QFutureInterface<void> &future, CppPreprocessor *preproc, @@ -166,6 +161,8 @@ private: // project integration QMap<ProjectExplorer::Project *, ProjectInfo> m_projects; + mutable QMutex mutex; + enum { MAX_SELECTION_COUNT = 5 }; diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h index 11be08a4b0..e3ad4fe961 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.h +++ b/src/plugins/cpptools/cppmodelmanagerinterface.h @@ -38,6 +38,7 @@ #include <cplusplus/CppDocument.h> #include <QtCore/QObject> #include <QtCore/QMap> +#include <QtCore/QPointer> namespace ProjectExplorer { class Project; @@ -51,10 +52,29 @@ class CPPTOOLS_EXPORT CppModelManagerInterface Q_OBJECT public: - typedef QMap<QString, CPlusPlus::Document::Ptr> DocumentTable; + typedef QMap<QString, CPlusPlus::Document::Ptr> DocumentTable; // ### remove me - struct ProjectInfo + class ProjectInfo { + public: + ProjectInfo() + { } + + ProjectInfo(QPointer<ProjectExplorer::Project> project) + : project(project) + { } + + operator bool() const + { return ! project.isNull(); } + + bool isValid() const + { return ! project.isNull(); } + + bool isNull() const + { return project.isNull(); } + + public: // attributes + QPointer<ProjectExplorer::Project> project; QString projectPath; QByteArray defines; QStringList sourceFiles; @@ -69,10 +89,12 @@ public: virtual void GC() = 0; virtual void updateSourceFiles(const QStringList &sourceFiles) = 0; - virtual CPlusPlus::Document::Ptr document(const QString &fileName) = 0; - virtual DocumentTable documents() = 0; + virtual CPlusPlus::Document::Ptr document(const QString &fileName) const = 0; + virtual DocumentTable documents() const = 0; - virtual ProjectInfo *projectInfo(ProjectExplorer::Project *project) = 0; + virtual QList<ProjectInfo> projectInfos() const = 0; + virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0; + virtual void updateProjectInfo(const ProjectInfo &pinfo) = 0; }; } // namespace CppTools diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index 8a096900eb..92905e42ef 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -10,7 +10,7 @@ unix:QMAKE_CXXFLAGS_DEBUG += -O3 INCLUDEPATH += . DEFINES += CPPTOOLS_LIBRARY CONFIG += help -include(rpp/rpp.pri)|error("Can't find RPP") + HEADERS += cpptools_global.h \ cppquickopenfilter.h \ cppclassesfilter.h \ diff --git a/src/plugins/cpptools/rpp/pp-cctype.h b/src/plugins/cpptools/rpp/pp-cctype.h deleted file mode 100644 index 62b44f0bf4..0000000000 --- a/src/plugins/cpptools/rpp/pp-cctype.h +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef PP_CCTYPE_H -#define PP_CCTYPE_H - -#include <cctype> - -namespace rpp { - -inline bool pp_isalpha (int __ch) -{ return std::isalpha ((unsigned char) __ch) != 0; } - -inline bool pp_isalnum (int __ch) -{ return std::isalnum ((unsigned char) __ch) != 0; } - -inline bool pp_isdigit (int __ch) -{ return std::isdigit ((unsigned char) __ch) != 0; } - -inline bool pp_isspace (int __ch) -{ return std::isspace ((unsigned char) __ch) != 0; } - -} // namespace rpp - -#endif // PP_CCTYPE_H diff --git a/src/plugins/cpptools/rpp/pp-client.h b/src/plugins/cpptools/rpp/pp-client.h deleted file mode 100644 index 974004a6ce..0000000000 --- a/src/plugins/cpptools/rpp/pp-client.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ - -#ifndef PP_CLIENT_H -#define PP_CLIENT_H - -#include <QByteArray> -#include <QString> -#include <QFile> - -namespace rpp { - -class Macro; - -class Client -{ - Client(const Client &other); - void operator=(const Client &other); - -public: - enum IncludeType { - IncludeLocal, - IncludeGlobal - }; - -public: - Client() - { } - - virtual ~Client() - { } - - virtual void macroAdded(const QByteArray ¯oId, const QByteArray &text) = 0; - virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature. - - virtual void startExpandingMacro(unsigned offset, - const Macro ¯o, - const QByteArray &originalTextt) = 0; - - virtual void stopExpandingMacro(unsigned offset, - const Macro ¯o) = 0; - - virtual void startSkippingBlocks(unsigned offset) = 0; - virtual void stopSkippingBlocks(unsigned offset) = 0; -}; - -} // namespace rpp - -#endif // PP_CLIENT_H diff --git a/src/plugins/cpptools/rpp/pp-engine.cpp b/src/plugins/cpptools/rpp/pp-engine.cpp deleted file mode 100644 index 66e8957f35..0000000000 --- a/src/plugins/cpptools/rpp/pp-engine.cpp +++ /dev/null @@ -1,1124 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "pp.h" - -#include <Lexer.h> -#include <Token.h> -#include <QtDebug> -#include <algorithm> - -using namespace rpp; -using namespace CPlusPlus; - -namespace { - -class RangeLexer -{ - const Token *first; - const Token *last; - Token trivial; - -public: - inline RangeLexer(const Token *first, const Token *last) - : first(first), last(last) - { - // WARN: `last' must be a valid iterator. - trivial.offset = last->offset; - } - - inline operator bool() const - { return first != last; } - - inline bool isValid() const - { return first != last; } - - inline int size() const - { return std::distance(first, last); } - - inline const Token *dot() const - { return first; } - - inline const Token &operator*() const - { - if (first != last) - return *first; - - return trivial; - } - - inline const Token *operator->() const - { - if (first != last) - return first; - - return &trivial; - } - - inline RangeLexer &operator++() - { - ++first; - return *this; - } -}; - -class ExpressionEvaluator -{ - ExpressionEvaluator(const ExpressionEvaluator &other); - void operator = (const ExpressionEvaluator &other); - -public: - ExpressionEvaluator(Environment *env) - : env(env), _lex(0) - { } - - Value operator()(const Token *firstToken, const Token *lastToken, - const QByteArray &source) - { - this->source = source; - const Value previousValue = switchValue(Value()); - RangeLexer tmp(firstToken, lastToken); - RangeLexer *previousLex = _lex; - _lex = &tmp; - process_expression(); - _lex = previousLex; - return switchValue(previousValue); - } - -protected: - Value switchValue(const Value &value) - { - Value previousValue = _value; - _value = value; - return previousValue; - } - - bool isTokenDefined() const - { - if ((*_lex)->isNot(T_IDENTIFIER)) - return false; - const QByteArray spell = tokenSpell(); - if (spell.size() != 7) - return false; - return spell == "defined"; - } - - QByteArray tokenSpell() const - { - const QByteArray text = QByteArray::fromRawData(source.constData() + (*_lex)->offset, - (*_lex)->length); - return text; - } - - bool process_expression() - { return process_constant_expression(); } - - bool process_primary() - { - if ((*_lex)->is(T_INT_LITERAL)) { - _value.set_long(tokenSpell().toLong()); - ++(*_lex); - return true; - } else if (isTokenDefined()) { - ++(*_lex); - if ((*_lex)->is(T_IDENTIFIER)) { - _value.set_long(env->resolve(tokenSpell()) != 0); - ++(*_lex); - return true; - } else if ((*_lex)->is(T_LPAREN)) { - ++(*_lex); - if ((*_lex)->is(T_IDENTIFIER)) { - _value.set_long(env->resolve(tokenSpell()) != 0); - ++(*_lex); - if ((*_lex)->is(T_RPAREN)) { - ++(*_lex); - return true; - } - } - return false; - } - return true; - } else if ((*_lex)->is(T_IDENTIFIER)) { - _value.set_long(0); - ++(*_lex); - return true; - } else if ((*_lex)->is(T_MINUS)) { - ++(*_lex); - process_primary(); - _value.set_long(- _value.l); - return true; - } else if ((*_lex)->is(T_PLUS)) { - ++(*_lex); - process_primary(); - return true; - } else if ((*_lex)->is(T_EXCLAIM)) { - ++(*_lex); - process_primary(); - _value.set_long(_value.is_zero()); - return true; - } else if ((*_lex)->is(T_LPAREN)) { - ++(*_lex); - process_expression(); - if ((*_lex)->is(T_RPAREN)) - ++(*_lex); - return true; - } - - return false; - } - - bool process_multiplicative() - { - process_primary(); - - while ((*_lex)->is(T_STAR) || (*_lex)->is(T_SLASH) || (*_lex)->is(T_PERCENT)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_primary(); - - if (op.is(T_STAR)) { - _value = left * _value; - } else if (op.is(T_SLASH)) { - if (_value.is_zero()) - _value.set_long(0); - else - _value = left / _value; - } else if (op.is(T_PERCENT)) { - if (_value.is_zero()) - _value.set_long(0); - else - _value = left % _value; - } - } - - return true; - } - - bool process_additive() - { - process_multiplicative(); - - while ((*_lex)->is(T_PLUS) || (*_lex)->is(T_MINUS)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_multiplicative(); - - if (op.is(T_PLUS)) - _value = left + _value; - else if (op.is(T_MINUS)) - _value = left - _value; - } - - return true; - } - - bool process_shift() - { - process_additive(); - - while ((*_lex)->is(T_MINUS_MINUS) || (*_lex)->is(T_GREATER_GREATER)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_additive(); - - if (op.is(T_MINUS_MINUS)) - _value = left << _value; - else if (op.is(T_GREATER_GREATER)) - _value = left >> _value; - } - - return true; - } - - bool process_relational() - { - process_shift(); - - while ((*_lex)->is(T_LESS) || (*_lex)->is(T_LESS_EQUAL) || - (*_lex)->is(T_GREATER) || (*_lex)->is(T_GREATER_EQUAL)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_shift(); - - if (op.is(T_LESS)) - _value = left < _value; - else if (op.is(T_LESS_EQUAL)) - _value = left <= _value; - else if (op.is(T_GREATER)) - _value = left > _value; - else if (op.is(T_GREATER_EQUAL)) - _value = left >= _value; - } - - return true; - } - - bool process_equality() - { - process_relational(); - - while ((*_lex)->is(T_EXCLAIM_EQUAL) || (*_lex)->is(T_EQUAL_EQUAL)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_relational(); - - if (op.is(T_EXCLAIM_EQUAL)) - _value = left != _value; - else if (op.is(T_EQUAL_EQUAL)) - _value = left == _value; - } - - return true; - } - - bool process_and() - { - process_equality(); - - while ((*_lex)->is(T_AMPER)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_equality(); - - _value = left & _value; - } - - return true; - } - - bool process_xor() - { - process_and(); - - while ((*_lex)->is(T_CARET)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_and(); - - _value = left ^ _value; - } - - return true; - } - - bool process_or() - { - process_xor(); - - while ((*_lex)->is(T_CARET)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_xor(); - - _value = left | _value; - } - - return true; - } - - bool process_logical_and() - { - process_or(); - - while ((*_lex)->is(T_AMPER_AMPER)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_or(); - - _value = left && _value; - } - - return true; - } - - bool process_logical_or() - { - process_logical_and(); - - while ((*_lex)->is(T_PIPE_PIPE)) { - const Token op = *(*_lex); - ++(*_lex); - - const Value left = _value; - process_logical_and(); - - _value = left || _value; - } - - return true; - } - - bool process_constant_expression() - { - process_logical_or(); - const Value cond = _value; - if ((*_lex)->is(T_QUESTION)) { - ++(*_lex); - process_constant_expression(); - Value left = _value, right; - if ((*_lex)->is(T_COLON)) { - ++(*_lex); - process_constant_expression(); - right = _value; - } - _value = ! cond.is_zero() ? left : right; - } - - return true; - } - -private: - Environment *env; - QByteArray source; - RangeLexer *_lex; - Value _value; -}; - -} // end of anonymous namespace - - -pp::pp (Client *client, Environment &env) - : client(client), - env(env), - expand(env) -{ - resetIfLevel (); -} - -void pp::pushState(const State &s) -{ - _savedStates.append(state()); - _source = s.source; - _tokens = s.tokens; - _dot = s.dot; -} - -pp::State pp::state() const -{ - State state; - state.source = _source; - state.tokens = _tokens; - state.dot = _dot; - return state; -} - -void pp::popState() -{ - const State &state = _savedStates.last(); - _source = state.source; - _tokens = state.tokens; - _dot = state.dot; - _savedStates.removeLast(); -} - -void pp::operator () (const QByteArray &filename, - const QByteArray &source, - QByteArray *result) -{ - const QByteArray previousFile = env.current_file; - env.current_file = filename; - - operator () (source, result); - - env.current_file = previousFile; -} - -pp::State pp::createStateFromSource(const QByteArray &source) const -{ - State state; - state.source = source; - Lexer lex(state.source.constBegin(), state.source.constEnd()); - lex.setScanKeywords(false); - Token tok; - do { - lex(&tok); - state.tokens.append(tok); - } while (tok.isNot(T_EOF_SYMBOL)); - state.dot = state.tokens.constBegin(); - return state; -} - -void pp::operator()(const QByteArray &source, QByteArray *result) -{ - pushState(createStateFromSource(source)); - - const unsigned previousCurrentLine = env.currentLine; - env.currentLine = 0; - - while (true) { - if (env.currentLine != _dot->lineno) { - if (env.currentLine > _dot->lineno) { - result->append("\n# "); - result->append(QByteArray::number(_dot->lineno)); - result->append(' '); - result->append('"'); - result->append(env.current_file); - result->append('"'); - result->append('\n'); - } else { - for (unsigned i = env.currentLine; i < _dot->lineno; ++i) - result->append('\n'); - } - env.currentLine = _dot->lineno; - } - - if (_dot->is(T_EOF_SYMBOL)) { - break; - } else if (_dot->is(T_POUND) && (! _dot->joined && _dot->newline)) { - TokenIterator start = _dot; - do { - ++_dot; - } while (_dot->isNot(T_EOF_SYMBOL) && (_dot->joined || ! _dot->newline)); - - //qDebug() << QByteArray(first + beginPP.offset, - //tokens.last().end() - beginPP.offset); - - const bool skippingBlocks = _skipping[iflevel]; - - processDirective(start, _dot); - - if (client && skippingBlocks != _skipping[iflevel]) { - unsigned offset = start->offset; - if (_skipping[iflevel]) { - if (_dot->newline) - ++offset; - client->startSkippingBlocks(offset); - } else { - if (offset) - --offset; - client->stopSkippingBlocks(offset); - } - } - } else if (skipping()) { - do { - ++_dot; - } while (_dot->isNot(T_EOF_SYMBOL) && (_dot->joined || ! _dot->newline)); - } else { - if (_dot->joined) - result->append("\\\n"); - else if (_dot->whitespace) - result->append(' '); - - if (_dot->isNot(T_IDENTIFIER)) { - result->append(tokenSpell(*_dot)); - ++_dot; - } else { - const TokenIterator identifierToken = _dot; - ++_dot; // skip T_IDENTIFIER - - const QByteArray spell = tokenSpell(*identifierToken); - if (env.isBuiltinMacro(spell)) { - const Macro trivial; - - if (client) - client->startExpandingMacro(identifierToken->offset, - trivial, spell); - - expand(spell.constBegin(), spell.constEnd(), result); - - if (client) - client->stopExpandingMacro(_dot->offset, trivial); - - continue; - } - - Macro *m = env.resolve(spell); - if (! m) { - result->append(spell); - } else { - if (! m->function_like) { - if (_dot->isNot(T_LPAREN)) { - if (client) - client->startExpandingMacro(identifierToken->offset, - *m, spell); - - m->hidden = true; - - expand(m->definition.constBegin(), - m->definition.constEnd(), - result); - - if (client) - client->stopExpandingMacro(_dot->offset, *m); - - m->hidden = false; - continue; - } else { - QByteArray tmp; - m->hidden = true; - - if (client) - client->startExpandingMacro(identifierToken->offset, - *m, spell); - - expand(m->definition.constBegin(), - m->definition.constEnd(), - &tmp); - - if (client) - client->stopExpandingMacro(_dot->offset, *m); - - m->hidden = false; - - m = 0; // reset the active the macro - - pushState(createStateFromSource(tmp)); - if (_dot->is(T_IDENTIFIER)) { - const QByteArray id = tokenSpell(*_dot); - Macro *macro = env.resolve(id); - if (macro && macro->function_like) - m = macro; - } - popState(); - - if (! m) { - result->append(tmp); - continue; - } - } - } - - // collect the actual arguments - if (_dot->isNot(T_LPAREN)) { - // ### warnng expected T_LPAREN - result->append(m->name); - continue; - } - - int count = 0; - while (_dot->isNot(T_EOF_SYMBOL)) { - if (_dot->is(T_LPAREN)) - ++count; - else if (_dot->is(T_RPAREN)) { - if (! --count) - break; - } - ++_dot; - } - if (_dot->isNot(T_RPAREN)) { - // ### warning expected T_RPAREN - } else { - const char *beginOfText = startOfToken(*identifierToken); - const char *endOfText = endOfToken(*_dot); - ++_dot; // skip T_RPAREN - - if (client) { - const QByteArray text = - QByteArray::fromRawData(beginOfText, - endOfText - beginOfText); - - client->startExpandingMacro(identifierToken->offset, - *m, text); - } - - expand(beginOfText, endOfText, result); - - if (client) - client->stopExpandingMacro(_dot->offset, *m); - } - } - } - } - } - - popState(); - env.currentLine = previousCurrentLine; -} - -const char *pp::startOfToken(const Token &token) const -{ return _source.constBegin() + token.begin(); } - -const char *pp::endOfToken(const Token &token) const -{ return _source.constBegin() + token.end(); } - -QByteArray pp::tokenSpell(const Token &token) const -{ - const QByteArray text = QByteArray::fromRawData(_source.constBegin() + token.offset, - token.length); - return text; -} - -QByteArray pp::tokenText(const Token &token) const -{ - const QByteArray text(_source.constBegin() + token.offset, - token.length); - return text; -} - -void pp::processDirective(TokenIterator firstToken, TokenIterator lastToken) -{ - RangeLexer tk(firstToken, lastToken); - ++tk; // skip T_POUND - - if (tk->is(T_IDENTIFIER)) { - const QByteArray directive = tokenSpell(*tk); - switch (PP_DIRECTIVE_TYPE d = classifyDirective(directive)) { - case PP_DEFINE: - if (! skipping()) - processDefine(firstToken, lastToken); - break; - - case PP_INCLUDE: - case PP_INCLUDE_NEXT: - if (! skipping()) - processInclude(d == PP_INCLUDE_NEXT, firstToken, lastToken); - break; - - case PP_UNDEF: - if (! skipping()) - processUndef(firstToken, lastToken); - break; - - case PP_ELIF: - processElif(firstToken, lastToken); - break; - - case PP_ELSE: - processElse(firstToken, lastToken); - break; - - case PP_ENDIF: - processEndif(firstToken, lastToken); - break; - - case PP_IF: - processIf(firstToken, lastToken); - break; - - case PP_IFDEF: - case PP_IFNDEF: - processIfdef(d == PP_IFNDEF, firstToken, lastToken); - break; - - default: - break; - } // switch - } -} - -QVector<Token> pp::tokenize(const QByteArray &text) const -{ - QVector<Token> tokens; - Lexer lex(text.constBegin(), text.constEnd()); - lex.setScanKeywords(false); - Token tk; - do { - lex(&tk); - tokens.append(tk); - } while (tk.isNot(T_EOF_SYMBOL)); - return tokens; -} - -void pp::processInclude(bool skipCurentPath, - TokenIterator firstToken, TokenIterator lastToken, - bool acceptMacros) -{ - RangeLexer tk(firstToken, lastToken); - ++tk; // skip T_POUND - ++tk; // skip `include|nclude_next' - - if (acceptMacros && tk->is(T_IDENTIFIER)) { -#if 0 - QByteArray name; - name.reserve(256); - MacroExpander expandInclude(env); - expandInclude(startOfToken(tokens.at(2)), - startOfToken(tokens.last()), - &name); - const QByteArray previousSource = switchSource(name); - //processInclude(skipCurentPath, tokenize(name), /*accept macros=*/ false); - (void) switchSource(previousSource); -#endif - } else if (tk->is(T_LESS)) { - TokenIterator start = tk.dot(); - for (; tk->isNot(T_EOF_SYMBOL); ++tk) { - if (tk->is(T_GREATER)) - break; - } - const char *beginOfPath = endOfToken(*start); - const char *endOfPath = startOfToken(*tk); - const QByteArray path = QByteArray::fromRawData(beginOfPath, - endOfPath - beginOfPath); - - QString fn = QString::fromUtf8(path.constData(), path.length()); - - if (client) - client->sourceNeeded(fn, Client::IncludeGlobal); - } else if (tk->is(T_ANGLE_STRING_LITERAL) || tk->is(T_STRING_LITERAL)) { - const QByteArray spell = tokenSpell(*tk); - const char *beginOfPath = spell.constBegin(); - const char *endOfPath = spell.constEnd(); - const char quote = *beginOfPath; - if (beginOfPath + 1 != endOfPath && ((quote == '"' && endOfPath[-1] == '"') || - (quote == '<' && endOfPath[-1] == '>'))) { - const QByteArray path = QByteArray::fromRawData(beginOfPath + 1, - spell.length() - 2); - QString fn = QString::fromUtf8(path.constData(), path.length()); - - if (client) - client->sourceNeeded(fn, Client::IncludeLocal); - } - } -} - -void pp::processDefine(TokenIterator firstToken, TokenIterator lastToken) -{ - RangeLexer tk(firstToken, lastToken); - - if (tk.size() < 3) - return; // nothing to do - - ++tk; // skip T_POUND - ++tk; // skip T_DEFINE - - if (tk->isNot(T_IDENTIFIER)) { - // ### warning expected an `identifier' - return; - } - - Macro macro; - macro.name = tokenText(*tk); - ++tk; // skip T_IDENTIFIER - - if (tk->is(T_LPAREN) && ! tk->whitespace) { - // a function-like macro definition - macro.function_like = true; - - ++tk; // skip T_LPAREN - if (tk->is(T_IDENTIFIER)) { - macro.formals.append(tokenText(*tk)); - ++tk; // skip T_IDENTIFIER - while (tk->is(T_COMMA)) { - ++tk;// skip T_COMMA - if (tk->isNot(T_IDENTIFIER)) - break; - macro.formals.append(tokenText(*tk)); - ++tk; // skip T_IDENTIFIER - } - } - - if (tk->is(T_DOT_DOT_DOT)) { - macro.variadics = true; - ++tk; // skip T_DOT_DOT_DOT - } - - if (tk->isNot(T_RPAREN)) { - // ### warning expected `)' - return; - } - - ++tk; // skip T_RPAREN - } - - QByteArray macroId = macro.name; - const bool isQtWord = isQtReservedWord(macroId); - - if (macro.function_like) { - macroId += '('; - for (int i = 0; i < macro.formals.size(); ++i) { - if (i != 0) - macroId += ", "; - - const QByteArray formal = macro.formals.at(i); - macroId += formal; - } - macroId += ')'; - } - - if (isQtWord) - macro.definition = macroId; - else { - // ### make me fast! - const char *startOfDefinition = startOfToken(*tk); - const char *endOfDefinition = startOfToken(*lastToken); - macro.definition.append(startOfDefinition, - endOfDefinition - startOfDefinition); - macro.definition.replace("\\\n", " "); - macro.definition.replace('\n', ' '); - macro.definition = macro.definition.trimmed(); - } - - env.bind(macro); - - QByteArray macroText; - macroText.reserve(64); - macroText += "#define "; - - macroText += macroId; - macroText += ' '; - macroText += macro.definition; - macroText += '\n'; - - client->macroAdded(macroId, macroText); -} - -void pp::processIf(TokenIterator firstToken, TokenIterator lastToken) -{ - RangeLexer tk(firstToken, lastToken); - - ++tk; // skip T_POUND - ++tk; // skipt `if' - - if (testIfLevel()) { - const char *first = startOfToken(*tk); - const char *last = startOfToken(*lastToken); - - MacroExpander expandCondition (env); - QByteArray condition; - condition.reserve(256); - expandCondition(first, last, &condition); - - QVector<Token> tokens = tokenize(condition); - - const Value result = evalExpression(tokens.constBegin(), - tokens.constEnd() - 1, - condition); - - _true_test[iflevel] = ! result.is_zero (); - _skipping[iflevel] = result.is_zero (); - } -} - -void pp::processElse(TokenIterator firstToken, TokenIterator lastToken) -{ - RangeLexer tk(firstToken, lastToken); - - if (iflevel == 0 && !skipping ()) { - // std::cerr << "*** WARNING #else without #if" << std::endl; - } else if (iflevel > 0 && _skipping[iflevel - 1]) { - _skipping[iflevel] = true; - } else { - _skipping[iflevel] = _true_test[iflevel]; - } -} - -void pp::processElif(TokenIterator firstToken, TokenIterator lastToken) -{ - RangeLexer tk(firstToken, lastToken); - ++tk; // skip T_POUND - ++tk; // skipt `elif' - - if (! (iflevel > 0)) { - // std::cerr << "*** WARNING: " << __FILE__ << __LINE__ << std::endl; - } else if (iflevel == 0 && !skipping()) { - // std::cerr << "*** WARNING #else without #if" << std::endl; - } else if (!_true_test[iflevel] && !_skipping[iflevel - 1]) { - const Value result = evalExpression(tk.dot(), lastToken, _source); - _true_test[iflevel] = ! result.is_zero (); - _skipping[iflevel] = result.is_zero (); - } else { - _skipping[iflevel] = true; - } -} - -void pp::processEndif(TokenIterator, TokenIterator) -{ - if (iflevel == 0 && !skipping()) { - // std::cerr << "*** WARNING #endif without #if" << std::endl; - } else { - _skipping[iflevel] = false; - _true_test[iflevel] = false; - - --iflevel; - } -} - -void pp::processIfdef(bool checkUndefined, - TokenIterator firstToken, TokenIterator lastToken) -{ - RangeLexer tk(firstToken, lastToken); - - ++tk; // skip T_POUND - ++tk; // skip `ifdef' - if (testIfLevel()) { - if (tk->is(T_IDENTIFIER)) { - const QByteArray macroName = tokenSpell(*tk); - bool value = env.resolve(macroName) != 0 || env.isBuiltinMacro(macroName); - - if (checkUndefined) - value = ! value; - - _true_test[iflevel] = value; - _skipping [iflevel] = ! value; - } - } -} - -void pp::processUndef(TokenIterator firstToken, TokenIterator lastToken) -{ - RangeLexer tk(firstToken, lastToken); - - ++tk; // skip T_POUND - ++tk; // skip `undef' - - if (tk->is(T_IDENTIFIER)) { - const QByteArray macroName = tokenText(*tk); - env.remove(macroName); - - QByteArray macroText; - macroText += "#undef "; - macroText += macroName; - macroText += '\n'; - client->macroAdded(macroName, macroText); - } -} - -void pp::resetIfLevel () -{ - iflevel = 0; - _skipping[iflevel] = false; - _true_test[iflevel] = false; -} - -pp::PP_DIRECTIVE_TYPE pp::classifyDirective (const QByteArray &__directive) const -{ - switch (__directive.size()) - { - case 2: - if (__directive[0] == 'i' && __directive[1] == 'f') - return PP_IF; - break; - - case 4: - if (__directive[0] == 'e' && __directive == "elif") - return PP_ELIF; - else if (__directive[0] == 'e' && __directive == "else") - return PP_ELSE; - break; - - case 5: - if (__directive[0] == 'i' && __directive == "ifdef") - return PP_IFDEF; - else if (__directive[0] == 'u' && __directive == "undef") - return PP_UNDEF; - else if (__directive[0] == 'e' && __directive == "endif") - return PP_ENDIF; - break; - - case 6: - if (__directive[0] == 'i' && __directive == "ifndef") - return PP_IFNDEF; - else if (__directive[0] == 'd' && __directive == "define") - return PP_DEFINE; - break; - - case 7: - if (__directive[0] == 'i' && __directive == "include") - return PP_INCLUDE; - break; - - case 12: - if (__directive[0] == 'i' && __directive == "include_next") - return PP_INCLUDE_NEXT; - break; - - default: - break; - } - - return PP_UNKNOWN_DIRECTIVE; -} - -bool pp::testIfLevel() -{ - const bool result = !_skipping[iflevel++]; - _skipping[iflevel] = _skipping[iflevel - 1]; - _true_test[iflevel] = false; - return result; -} - -int pp::skipping() const -{ return _skipping[iflevel]; } - -Value pp::evalExpression(TokenIterator firstToken, TokenIterator lastToken, - const QByteArray &source) const -{ - ExpressionEvaluator eval(&env); - const Value result = eval(firstToken, lastToken, source); - return result; -} - -bool pp::isQtReservedWord (const QByteArray ¯oId) const -{ - const int size = macroId.size(); - if (size == 9 && macroId.at(0) == 'Q' && macroId == "Q_SIGNALS") - return true; - else if (size == 7 && macroId.at(0) == 'Q' && macroId == "Q_SLOTS") - return true; - else if (size == 6 && macroId.at(0) == 'S' && macroId == "SIGNAL") - return true; - else if (size == 4 && macroId.at(0) == 'S' && macroId == "SLOT") - return true; - else if (size == 7 && macroId.at(0) == 's' && macroId == "signals") - return true; - else if (size == 5 && macroId.at(0) == 's' && macroId == "slots") - return true; - return false; -} diff --git a/src/plugins/cpptools/rpp/pp-engine.h b/src/plugins/cpptools/rpp/pp-engine.h deleted file mode 100644 index 13135f6a31..0000000000 --- a/src/plugins/cpptools/rpp/pp-engine.h +++ /dev/null @@ -1,231 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef PP_ENGINE_H -#define PP_ENGINE_H - -#include "pp-client.h" - -#include <Token.h> -#include <QVector> - -namespace CPlusPlus { - class Token; -} - -namespace rpp { - - struct Value - { - enum Kind { - Kind_Long, - Kind_ULong, - }; - - Kind kind; - - union { - long l; - unsigned long ul; - }; - - - Value() - : kind(Kind_Long), l(0) - { } - - inline bool is_ulong () const - { return kind == Kind_ULong; } - - inline void set_ulong (unsigned long v) - { - ul = v; - kind = Kind_ULong; - } - - inline void set_long (long v) - { - l = v; - kind = Kind_Long; - } - - inline bool is_zero () const - { return l == 0; } - -#define PP_DEFINE_BIN_OP(name, op) \ - inline Value operator op(const Value &other) const \ - { \ - Value v = *this; \ - if (v.is_ulong () || other.is_ulong ()) \ - v.set_ulong (v.ul op other.ul); \ - else \ - v.set_long (v.l op other.l); \ - return v; \ - } - - PP_DEFINE_BIN_OP(op_add, +) - PP_DEFINE_BIN_OP(op_sub, -) - PP_DEFINE_BIN_OP(op_mult, *) - PP_DEFINE_BIN_OP(op_div, /) - PP_DEFINE_BIN_OP(op_mod, %) - PP_DEFINE_BIN_OP(op_lhs, <<) - PP_DEFINE_BIN_OP(op_rhs, >>) - PP_DEFINE_BIN_OP(op_lt, <) - PP_DEFINE_BIN_OP(op_gt, >) - PP_DEFINE_BIN_OP(op_le, <=) - PP_DEFINE_BIN_OP(op_ge, >=) - PP_DEFINE_BIN_OP(op_eq, ==) - PP_DEFINE_BIN_OP(op_ne, !=) - PP_DEFINE_BIN_OP(op_bit_and, &) - PP_DEFINE_BIN_OP(op_bit_or, |) - PP_DEFINE_BIN_OP(op_bit_xor, ^) - PP_DEFINE_BIN_OP(op_and, &&) - PP_DEFINE_BIN_OP(op_or, ||) - -#undef PP_DEFINE_BIN_OP - }; - - class pp - { - Client *client; - Environment &env; - MacroExpander expand; - - enum { MAX_LEVEL = 512 }; - - bool _skipping[MAX_LEVEL]; // ### move in state - bool _true_test[MAX_LEVEL]; // ### move in state - int iflevel; // ### move in state - - enum PP_DIRECTIVE_TYPE - { - PP_UNKNOWN_DIRECTIVE, - PP_DEFINE, - PP_INCLUDE, - PP_INCLUDE_NEXT, - PP_ELIF, - PP_ELSE, - PP_ENDIF, - PP_IF, - PP_IFDEF, - PP_IFNDEF, - PP_UNDEF - }; - - typedef const CPlusPlus::Token *TokenIterator; - - struct State { - QByteArray source; - QVector<CPlusPlus::Token> tokens; - TokenIterator dot; - }; - - QList<State> _savedStates; - - State state() const; - void pushState(const State &state); - void popState(); - - QByteArray _source; - QVector<CPlusPlus::Token> _tokens; - TokenIterator _dot; - - State createStateFromSource(const QByteArray &source) const; - - public: - pp(Client *client, Environment &env); - - void operator()(const QByteArray &filename, - const QByteArray &source, - QByteArray *result); - - void operator()(const QByteArray &source, - QByteArray *result); - - private: - void resetIfLevel(); - bool testIfLevel(); - int skipping() const; - - PP_DIRECTIVE_TYPE classifyDirective(const QByteArray &directive) const; - - Value evalExpression(TokenIterator firstToken, - TokenIterator lastToken, - const QByteArray &source) const; - - QVector<CPlusPlus::Token> tokenize(const QByteArray &text) const; - - const char *startOfToken(const CPlusPlus::Token &token) const; - const char *endOfToken(const CPlusPlus::Token &token) const; - - QByteArray tokenSpell(const CPlusPlus::Token &token) const; - QByteArray tokenText(const CPlusPlus::Token &token) const; // does a deep copy - - void processDirective(TokenIterator dot, TokenIterator lastToken); - void processInclude(bool skipCurrentPath, - TokenIterator dot, TokenIterator lastToken, - bool acceptMacros = true); - void processDefine(TokenIterator dot, TokenIterator lastToken); - void processIf(TokenIterator dot, TokenIterator lastToken); - void processElse(TokenIterator dot, TokenIterator lastToken); - void processElif(TokenIterator dot, TokenIterator lastToken); - void processEndif(TokenIterator dot, TokenIterator lastToken); - void processIfdef(bool checkUndefined, - TokenIterator dot, TokenIterator lastToken); - void processUndef(TokenIterator dot, TokenIterator lastToken); - - bool isQtReservedWord(const QByteArray &name) const; - }; - -} // namespace rpp - -#endif // PP_ENGINE_H diff --git a/src/plugins/cpptools/rpp/pp-environment.cpp b/src/plugins/cpptools/rpp/pp-environment.cpp deleted file mode 100644 index 85e432ae5b..0000000000 --- a/src/plugins/cpptools/rpp/pp-environment.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "pp-environment.h" -#include "pp.h" -#include <cstring> - -using namespace rpp; - -Environment::Environment () - : currentLine(0), - hide_next(false), - _macros(0), - _allocated_macros(0), - _macro_count(-1), - _hash(0), - _hash_count(401) -{ -} - -Environment::~Environment () -{ - if (_macros) { - qDeleteAll(firstMacro(), lastMacro()); - free(_macros); - } - - if (_hash) - free(_hash); -} - -unsigned Environment::macroCount () const -{ return _macro_count + 1; } - -Macro *Environment::macroAt (unsigned index) const -{ return _macros[index]; } - -Macro *Environment::bind(const Macro &__macro) -{ - Q_ASSERT(! __macro.name.isEmpty()); - - Macro *m = new Macro (__macro); - m->hashcode = hash_code(m->name); - m->fileName = current_file; - m->line = currentLine; - - if (++_macro_count == _allocated_macros) { - if (! _allocated_macros) - _allocated_macros = 401; - else - _allocated_macros <<= 1; - - _macros = (Macro **) realloc(_macros, sizeof(Macro *) * _allocated_macros); - } - - _macros[_macro_count] = m; - - if (! _hash || _macro_count > (_hash_count >> 1)) { - rehash(); - } else { - const unsigned h = m->hashcode % _hash_count; - m->next = _hash[h]; - _hash[h] = m; - } - - return m; -} - -void Environment::remove (const QByteArray &name) -{ - Macro macro; - macro.name = name; - macro.hidden = true; - bind(macro); -} - -bool Environment::isBuiltinMacro(const QByteArray &s) const -{ - if (s.length() != 8) - return false; - - if (s[0] == '_') { - if (s[1] == '_') { - if (s[2] == 'D') { - if (s[3] == 'A') { - if (s[4] == 'T') { - if (s[5] == 'E') { - if (s[6] == '_') { - if (s[7] == '_') { - return true; - } - } - } - } - } - } - else if (s[2] == 'F') { - if (s[3] == 'I') { - if (s[4] == 'L') { - if (s[5] == 'E') { - if (s[6] == '_') { - if (s[7] == '_') { - return true; - } - } - } - } - } - } - else if (s[2] == 'L') { - if (s[3] == 'I') { - if (s[4] == 'N') { - if (s[5] == 'E') { - if (s[6] == '_') { - if (s[7] == '_') { - return true; - } - } - } - } - } - } - else if (s[2] == 'T') { - if (s[3] == 'I') { - if (s[4] == 'M') { - if (s[5] == 'E') { - if (s[6] == '_') { - if (s[7] == '_') { - return true; - } - } - } - } - } - } - } - } - return false; -} - -Macro *Environment::resolve (const QByteArray &name) const -{ - if (! _macros) - return 0; - - Macro *it = _hash[hash_code (name) % _hash_count]; - for (; it; it = it->next) { - if (it->name != name) - continue; - else if (it->hidden) - return 0; - else break; - } - return it; -} - -unsigned Environment::hash_code (const QByteArray &s) -{ - unsigned hash_value = 0; - - for (int i = 0; i < s.size (); ++i) - hash_value = (hash_value << 5) - hash_value + s.at (i); - - return hash_value; -} - -void Environment::rehash() -{ - if (_hash) { - free(_hash); - _hash_count <<= 1; - } - - _hash = (Macro **) calloc(_hash_count, sizeof(Macro *)); - - for (Macro **it = firstMacro(); it != lastMacro(); ++it) { - Macro *m= *it; - const unsigned h = m->hashcode % _hash_count; - m->next = _hash[h]; - _hash[h] = m; - } -} diff --git a/src/plugins/cpptools/rpp/pp-environment.h b/src/plugins/cpptools/rpp/pp-environment.h deleted file mode 100644 index 5b97c492d7..0000000000 --- a/src/plugins/cpptools/rpp/pp-environment.h +++ /dev/null @@ -1,109 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef PP_ENVIRONMENT_H -#define PP_ENVIRONMENT_H - -#include <QVector> -#include <QByteArray> - -namespace rpp { - -struct Macro; - -class Environment -{ -public: - Environment(); - ~Environment(); - - unsigned macroCount() const; - Macro *macroAt(unsigned index) const; - - Macro *bind(const Macro ¯o); - void remove(const QByteArray &name); - - Macro *resolve(const QByteArray &name) const; - bool isBuiltinMacro(const QByteArray &name) const; - - const Macro *const *firstMacro() const - { return _macros; } - - Macro **firstMacro() - { return _macros; } - - const Macro *const *lastMacro() const - { return _macros + _macro_count + 1; } - - Macro **lastMacro() - { return _macros + _macro_count + 1; } - -private: - static unsigned hash_code (const QByteArray &s); - void rehash(); - -public: - QByteArray current_file; - unsigned currentLine; - bool hide_next; - -private: - Macro **_macros; - int _allocated_macros; - int _macro_count; - Macro **_hash; - int _hash_count; -}; - -} // namespace rpp - -#endif // PP_ENVIRONMENT_H diff --git a/src/plugins/cpptools/rpp/pp-internal.h b/src/plugins/cpptools/rpp/pp-internal.h deleted file mode 100644 index 13bc7c17e8..0000000000 --- a/src/plugins/cpptools/rpp/pp-internal.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef PP_INTERNAL_H -#define PP_INTERNAL_H - -#include <QByteArray> - -namespace rpp { -namespace _PP_internal { - -inline bool comment_p (const char *__first, const char *__last) -{ - if (__first == __last) - return false; - - if (*__first != '/') - return false; - - if (++__first == __last) - return false; - - return (*__first == '/' || *__first == '*'); -} - -} // _PP_internal -} // namespace rpp - -#endif // PP_INTERNAL_H diff --git a/src/plugins/cpptools/rpp/pp-macro-expander.cpp b/src/plugins/cpptools/rpp/pp-macro-expander.cpp deleted file mode 100644 index 6b569eb132..0000000000 --- a/src/plugins/cpptools/rpp/pp-macro-expander.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ - -#include "pp.h" -#include "pp-macro-expander.h" -#include <QDateTime> - -using namespace rpp; - -MacroExpander::MacroExpander (Environment &env, pp_frame *frame) - : env(env), frame(frame), - lines(0), generated_lines(0) -{ } - -const QByteArray *MacroExpander::resolve_formal(const QByteArray &__name) -{ - if (! (frame && frame->expanding_macro)) - return 0; - - const QVector<QByteArray> &formals = frame->expanding_macro->formals; - for (int index = 0; index < formals.size(); ++index) { - const QByteArray formal = formals.at(index); - - if (formal == __name && index < frame->actuals.size()) - return &frame->actuals.at(index); - } - - return 0; -} - -const char *MacroExpander::operator () (const char *__first, const char *__last, - QByteArray *__result) -{ - generated_lines = 0; - __first = skip_blanks (__first, __last); - lines = skip_blanks.lines; - - while (__first != __last) - { - if (*__first == '\n') - { - __result->append("\n# "); - __result->append(QByteArray::number(env.currentLine)); - __result->append(' '); - __result->append('"'); - __result->append(env.current_file); - __result->append('"'); - __result->append('\n'); - ++lines; - - __first = skip_blanks (++__first, __last); - lines += skip_blanks.lines; - - if (__first != __last && *__first == '#') - break; - } - else if (*__first == '#') - { - __first = skip_blanks (++__first, __last); - lines += skip_blanks.lines; - - const char *end_id = skip_identifier (__first, __last); - const QByteArray fast_name(__first, end_id - __first); - __first = end_id; - - if (const QByteArray *actual = resolve_formal (fast_name)) - { - __result->append('\"'); - - const char *actual_begin = actual->constData (); - const char *actual_end = actual_begin + actual->size (); - - for (const char *it = skip_whitespaces (actual_begin, actual_end); - it != actual_end; ++it) - { - if (*it == '"' || *it == '\\') - { - __result->append('\\'); - __result->append(*it); - } - else if (*it == '\n') - { - __result->append('"'); - __result->append('\n'); - __result->append('"'); - } - else - __result->append(*it); - } - - __result->append('\"'); - } - else - __result->append('#'); // ### warning message? - } - else if (*__first == '\"') - { - const char *next_pos = skip_string_literal (__first, __last); - lines += skip_string_literal.lines; - __result->append(__first, next_pos - __first); - __first = next_pos; - } - else if (*__first == '\'') - { - const char *next_pos = skip_char_literal (__first, __last); - lines += skip_char_literal.lines; - __result->append(__first, next_pos - __first); - __first = next_pos; - } - else if (_PP_internal::comment_p (__first, __last)) - { - __first = skip_comment_or_divop (__first, __last); - int n = skip_comment_or_divop.lines; - lines += n; - - while (n-- > 0) - __result->append('\n'); - } - else if (pp_isspace (*__first)) - { - for (; __first != __last; ++__first) - { - if (*__first == '\n' || !pp_isspace (*__first)) - break; - } - - __result->append(' '); - } - else if (pp_isdigit (*__first)) - { - const char *next_pos = skip_number (__first, __last); - lines += skip_number.lines; - __result->append(__first, next_pos - __first); - __first = next_pos; - } - else if (pp_isalpha (*__first) || *__first == '_') - { - const char *name_begin = __first; - const char *name_end = skip_identifier (__first, __last); - __first = name_end; // advance - - // search for the paste token - const char *next = skip_blanks (__first, __last); - bool paste = false; - if (next != __last && *next == '#') - { - paste = true; - ++next; - if (next != __last && *next == '#') - __first = skip_blanks(++next, __last); - } - - const QByteArray fast_name(name_begin, name_end - name_begin); - - if (const QByteArray *actual = resolve_formal (fast_name)) - { - const char *begin = actual->constData (); - const char *end = begin + actual->size (); - if (paste) { - for (--end; end != begin - 1; --end) { - if (! pp_isspace(*end)) - break; - } - ++end; - } - __result->append(begin, end - begin); - continue; - } - - Macro *macro = env.resolve (fast_name); - if (! macro || macro->hidden || env.hide_next) - { - if (fast_name.size () == 7 && fast_name [0] == 'd' && fast_name == "defined") - env.hide_next = true; - else - env.hide_next = false; - - if (fast_name.size () == 8 && fast_name [0] == '_' && fast_name [1] == '_') - { - if (fast_name == "__LINE__") - { - char buf [16]; - const size_t count = qsnprintf (buf, 16, "%d", env.currentLine + lines); - __result->append(buf, count); - continue; - } - - else if (fast_name == "__FILE__") - { - __result->append('"'); - __result->append(env.current_file); - __result->append('"'); - continue; - } - - else if (fast_name == "__DATE__") - { - __result->append('"'); - __result->append(QDate::currentDate().toString().toUtf8()); - __result->append('"'); - continue; - } - - else if (fast_name == "__TIME__") - { - __result->append('"'); - __result->append(QTime::currentTime().toString().toUtf8()); - __result->append('"'); - continue; - } - - } - - __result->append(name_begin, name_end - name_begin); - continue; - } - - if (! macro->function_like) - { - Macro *m = 0; - - if (! macro->definition.isEmpty()) - { - macro->hidden = true; - - QByteArray __tmp; - __tmp.reserve (256); - - MacroExpander expand_macro (env); - expand_macro (macro->definition.constBegin (), macro->definition.constEnd (), &__tmp); - generated_lines += expand_macro.lines; - - if (! __tmp.isEmpty ()) - { - const char *__tmp_begin = __tmp.constBegin(); - const char *__tmp_end = __tmp.constEnd(); - const char *__begin_id = skip_whitespaces (__tmp_begin, __tmp_end); - const char *__end_id = skip_identifier (__begin_id, __tmp_end); - - if (__end_id == __tmp_end) - { - const QByteArray __id (__begin_id, __end_id - __begin_id); - m = env.resolve (__id); - } - - if (! m) - *__result += __tmp; - } - - macro->hidden = false; - } - - if (! m) - continue; - - macro = m; - } - - // function like macro - const char *arg_it = skip_whitespaces (__first, __last); - - if (arg_it == __last || *arg_it != '(') - { - __result->append(name_begin, name_end - name_begin); - lines += skip_whitespaces.lines; - __first = arg_it; - continue; - } - - QVector<QByteArray> actuals; - actuals.reserve (5); - ++arg_it; // skip '(' - - MacroExpander expand_actual (env, frame); - - const char *arg_end = skip_argument_variadics (actuals, macro, arg_it, __last); - if (arg_it != arg_end) - { - const QByteArray actual (arg_it, arg_end - arg_it); - QByteArray expanded; - expand_actual (actual.constBegin (), actual.constEnd (), &expanded); - actuals.push_back (expanded); - arg_it = arg_end; - } - - while (arg_it != __last && *arg_end == ',') - { - ++arg_it; // skip ',' - - arg_end = skip_argument_variadics (actuals, macro, arg_it, __last); - const QByteArray actual (arg_it, arg_end - arg_it); - QByteArray expanded; - expand_actual (actual.constBegin (), actual.constEnd (), &expanded); - actuals.push_back (expanded); - arg_it = arg_end; - } - - if (! (arg_it != __last && *arg_it == ')')) - return __last; - - ++arg_it; // skip ')' - __first = arg_it; - - pp_frame frame (macro, actuals); - MacroExpander expand_macro (env, &frame); - macro->hidden = true; - expand_macro (macro->definition.constBegin (), macro->definition.constEnd (), __result); - macro->hidden = false; - generated_lines += expand_macro.lines; - } - else - __result->append(*__first++); - } - - return __first; -} - -const char *MacroExpander::skip_argument_variadics (QVector<QByteArray> const &__actuals, - Macro *__macro, - const char *__first, const char *__last) -{ - const char *arg_end = skip_argument (__first, __last); - - while (__macro->variadics && __first != arg_end && arg_end != __last && *arg_end == ',' - && (__actuals.size () + 1) == __macro->formals.size ()) - { - arg_end = skip_argument (++arg_end, __last); - } - - return arg_end; -} diff --git a/src/plugins/cpptools/rpp/pp-macro-expander.h b/src/plugins/cpptools/rpp/pp-macro-expander.h deleted file mode 100644 index dd11540c33..0000000000 --- a/src/plugins/cpptools/rpp/pp-macro-expander.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef PP_MACRO_EXPANDER_H -#define PP_MACRO_EXPANDER_H - -namespace rpp { - - struct pp_frame - { - Macro *expanding_macro; - const QVector<QByteArray> actuals; - - pp_frame (Macro *expanding_macro, const QVector<QByteArray> &actuals) - : expanding_macro (expanding_macro), - actuals (actuals) - { } - }; - - class MacroExpander - { - Environment &env; - pp_frame *frame; - - pp_skip_number skip_number; - pp_skip_identifier skip_identifier; - pp_skip_string_literal skip_string_literal; - pp_skip_char_literal skip_char_literal; - pp_skip_argument skip_argument; - pp_skip_comment_or_divop skip_comment_or_divop; - pp_skip_blanks skip_blanks; - pp_skip_whitespaces skip_whitespaces; - - const QByteArray *resolve_formal (const QByteArray &name); - - public: - MacroExpander (Environment &env, pp_frame *frame = 0); - - const char *operator () (const char *first, const char *last, - QByteArray *result); - - const char *skip_argument_variadics (const QVector<QByteArray> &actuals, - Macro *macro, - const char *first, const char *last); - - public: // attributes - int lines; - int generated_lines; - }; - -} // namespace rpp - -#endif // PP_MACRO_EXPANDER_H - diff --git a/src/plugins/cpptools/rpp/pp-macro.h b/src/plugins/cpptools/rpp/pp-macro.h deleted file mode 100644 index a7bbe35e1d..0000000000 --- a/src/plugins/cpptools/rpp/pp-macro.h +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef PP_MACRO_H -#define PP_MACRO_H - -#include <QByteArray> -#include <QVector> - -namespace rpp { - - struct Macro - { - QByteArray name; - QByteArray definition; - QVector<QByteArray> formals; - QByteArray fileName; - int line; - int lines; - Macro *next; - unsigned hashcode; - - union - { - unsigned state; - - struct - { - unsigned hidden: 1; - unsigned function_like: 1; - unsigned variadics: 1; - }; - }; - - inline Macro(): - line(0), - lines(0), - next(0), - hashcode(0), - state(0) - { } - }; - -} // namespace rpp - -#endif // PP_MACRO_H diff --git a/src/plugins/cpptools/rpp/pp-scanner.h b/src/plugins/cpptools/rpp/pp-scanner.h deleted file mode 100644 index 53fea70b52..0000000000 --- a/src/plugins/cpptools/rpp/pp-scanner.h +++ /dev/null @@ -1,380 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef PP_SCANNER_H -#define PP_SCANNER_H - -namespace rpp { - -struct pp_skip_blanks -{ - int lines; - - - const char *operator () (const char *__first, const char *__last) - { - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) - { - if (*__first == '\\') - { - const char *__begin = __first; - ++__begin; - - if (__begin != __last && *__begin == '\n') - ++__first; - else - break; - } - else if (*__first == '\n' || !pp_isspace (*__first)) - break; - } - - return __first; - } -}; - -struct pp_skip_whitespaces -{ - int lines; - - - const char *operator () (const char *__first, const char *__last) - { - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) - { - if (! pp_isspace (*__first)) - break; - } - - return __first; - } -}; - -struct pp_skip_comment_or_divop -{ - int lines; - - - const char *operator () (const char *__first, const char *__last) - { - enum { - MAYBE_BEGIN, - BEGIN, - MAYBE_END, - END, - IN_COMMENT, - IN_CXX_COMMENT - } state (MAYBE_BEGIN); - - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) - { - switch (state) - { - default: - assert (0); - break; - - case MAYBE_BEGIN: - if (*__first != '/') - return __first; - - state = BEGIN; - break; - - case BEGIN: - if (*__first == '*') - state = IN_COMMENT; - else if (*__first == '/') - state = IN_CXX_COMMENT; - else - return __first; - break; - - case IN_COMMENT: - if (*__first == '*') - state = MAYBE_END; - break; - - case IN_CXX_COMMENT: - if (*__first == '\n') - return __first; - break; - - case MAYBE_END: - if (*__first == '/') - state = END; - else if (*__first != '*') - state = IN_COMMENT; - break; - - case END: - return __first; - } - } - - return __first; - } -}; - -struct pp_skip_identifier -{ - int lines; - - - const char *operator () (const char *__first, const char *__last) - { - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) - { - if (! pp_isalnum (*__first) && *__first != '_') - break; - } - - return __first; - } -}; - -struct pp_skip_number -{ - int lines; - - - const char *operator () (const char *__first, const char *__last) - { - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) - { - if (! pp_isalnum (*__first) && *__first != '.') - break; - } - - return __first; - } -}; - -struct pp_skip_string_literal -{ - int lines; - - - const char *operator () (const char *__first, const char *__last) - { - enum { - BEGIN, - IN_STRING, - QUOTE, - END - } state (BEGIN); - - lines = 0; - - for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) - { - switch (state) - { - default: - assert (0); - break; - - case BEGIN: - if (*__first != '\"') - return __first; - state = IN_STRING; - break; - - case IN_STRING: - if (! (*__first != '\n')) - return __last; - - if (*__first == '\"') - state = END; - else if (*__first == '\\') - state = QUOTE; - break; - - case QUOTE: - state = IN_STRING; - break; - - case END: - return __first; - } - } - - return __first; - } -}; - -struct pp_skip_char_literal -{ - int lines; - - - const char *operator () (const char *__first, const char *__last) - { - enum { - BEGIN, - IN_STRING, - QUOTE, - END - } state (BEGIN); - - lines = 0; - - for (; state != END && __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) - { - switch (state) - { - default: - assert (0); - break; - - case BEGIN: - if (*__first != '\'') - return __first; - state = IN_STRING; - break; - - case IN_STRING: - if (! (*__first != '\n')) - return __last; - - if (*__first == '\'') - state = END; - else if (*__first == '\\') - state = QUOTE; - break; - - case QUOTE: - state = IN_STRING; - break; - } - } - - return __first; - } -}; - -struct pp_skip_argument -{ - pp_skip_identifier skip_number; - pp_skip_identifier skip_identifier; - pp_skip_string_literal skip_string_literal; - pp_skip_char_literal skip_char_literal; - pp_skip_comment_or_divop skip_comment_or_divop; - int lines; - - - const char *operator () (const char *__first, const char *__last) - { - int depth = 0; - lines = 0; - - while (__first != __last) - { - if (!depth && (*__first == ')' || *__first == ',')) - break; - else if (*__first == '(') - ++depth, ++__first; - else if (*__first == ')') - --depth, ++__first; - else if (*__first == '\"') - { - __first = skip_string_literal (__first, __last); - lines += skip_string_literal.lines; - } - else if (*__first == '\'') - { - __first = skip_char_literal (__first, __last); - lines += skip_char_literal.lines; - } - else if (*__first == '/') - { - __first = skip_comment_or_divop (__first, __last); - lines += skip_comment_or_divop.lines; - } - else if (pp_isalpha (*__first) || *__first == '_') - { - __first = skip_identifier (__first, __last); - lines += skip_identifier.lines; - } - else if (pp_isdigit (*__first)) - { - __first = skip_number (__first, __last); - lines += skip_number.lines; - } - else if (*__first == '\n') - { - ++__first; - ++lines; - } - else - ++__first; - } - - return __first; - } -}; - -} // namespace rpp - -#endif // PP_SCANNER_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/src/plugins/cpptools/rpp/pp.h b/src/plugins/cpptools/rpp/pp.h deleted file mode 100644 index 62f3245a28..0000000000 --- a/src/plugins/cpptools/rpp/pp.h +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Qt Software Information (qt-info@nokia.com) -** -** -** Non-Open Source Usage -** -** Licensees may use this file in accordance with the Qt Beta Version -** License Agreement, Agreement version 2.2 provided with the Software or, -** alternatively, in accordance with the terms contained in a written -** agreement between you and Nokia. -** -** GNU General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the packaging -** of this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** -** http://www.fsf.org/licensing/licenses/info/GPLv2.html and -** http://www.gnu.org/copyleft/gpl.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt GPL Exception -** version 1.2, included in the file GPL_EXCEPTION.txt in this package. -** -***************************************************************************/ -/* - Copyright 2005 Roberto Raggi <roberto@kdevelop.org> - - Permission to use, copy, modify, distribute, and sell this software and its - documentation for any purpose is hereby granted without fee, provided that - the above copyright notice appear in all copies and that both that - copyright notice and this permission notice appear in supporting - documentation. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef PP_H -#define PP_H - -#include <cassert> -#include <cstring> -#include <cctype> - -#include "pp-cctype.h" -#include "pp-internal.h" -#include "pp-macro.h" -#include "pp-environment.h" -#include "pp-scanner.h" -#include "pp-macro-expander.h" -#include "pp-engine.h" -#include "pp-client.h" - -#endif // PP_H diff --git a/src/plugins/cpptools/rpp/rpp.pri b/src/plugins/cpptools/rpp/rpp.pri deleted file mode 100644 index a79b0028a0..0000000000 --- a/src/plugins/cpptools/rpp/rpp.pri +++ /dev/null @@ -1,18 +0,0 @@ -DEPENDPATH += $$PWD -INCLUDEPATH += $$PWD - -HEADERS += $$PWD/pp-cctype.h \ - $$PWD/pp-engine.h \ - $$PWD/pp-environment.h \ - $$PWD/pp-internal.h \ - $$PWD/pp-macro-expander.h \ - $$PWD/pp-macro.h \ - $$PWD/pp-scanner.h \ - $$PWD/pp.h \ - $$PWD/pp-client.h - -SOURCES += $$PWD/pp-engine.cpp \ - $$PWD/pp-environment.cpp \ - $$PWD/pp-macro-expander.cpp - - diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp index 4b1e48abdf..308449ab58 100644 --- a/src/plugins/cpptools/searchsymbols.cpp +++ b/src/plugins/cpptools/searchsymbols.cpp @@ -40,7 +40,8 @@ using namespace CPlusPlus; using namespace CppTools::Internal; SearchSymbols::SearchSymbols(): - symbolsToSearchFor(Classes | Functions | Enums) + symbolsToSearchFor(Classes | Functions | Enums), + separateScope(false) { } @@ -49,6 +50,11 @@ void SearchSymbols::setSymbolsToSearchFor(SymbolTypes types) symbolsToSearchFor = types; } +void SearchSymbols::setSeparateScope(bool separateScope) +{ + this->separateScope = separateScope; +} + QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString &scope) { QString previousScope = switchScope(scope); @@ -73,13 +79,12 @@ bool SearchSymbols::visit(Enum *symbol) return false; QString name = symbolName(symbol); - QString previousScope = switchScope(name); - QIcon icon = icons.iconForSymbol(symbol); + QString scopedName = scopedSymbolName(name); + QString previousScope = switchScope(scopedName); + appendItem(separateScope ? name : scopedName, + separateScope ? previousScope : QString(), + ModelItemInfo::Enum, symbol); Scope *members = symbol->members(); - items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum, - QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), - symbol->line(), - icon)); for (unsigned i = 0; i < members->symbolCount(); ++i) { accept(members->symbolAt(i)); } @@ -93,18 +98,18 @@ bool SearchSymbols::visit(Function *symbol) return false; QString name = symbolName(symbol); - QString type = overview.prettyType(symbol->type()); - QIcon icon = icons.iconForSymbol(symbol); - items.append(ModelItemInfo(name, type, ModelItemInfo::Method, - QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), - symbol->line(), - icon)); + QString scopedName = scopedSymbolName(name); + QString type = overview.prettyType(symbol->type(), + separateScope ? symbol->name() : 0); + appendItem(separateScope ? type : scopedName, + separateScope ? _scope : type, + ModelItemInfo::Method, symbol); return false; } bool SearchSymbols::visit(Namespace *symbol) { - QString name = symbolName(symbol); + QString name = findOrInsert(scopedSymbolName(symbol)); QString previousScope = switchScope(name); Scope *members = symbol->members(); for (unsigned i = 0; i < members->symbolCount(); ++i) { @@ -118,12 +123,9 @@ bool SearchSymbols::visit(Namespace *symbol) bool SearchSymbols::visit(Declaration *symbol) { if (symbol->type()->isFunction()) { - QString name = symbolName(symbol); + QString name = scopedSymbolName(symbol); QString type = overview.prettyType(symbol->type()); - //QIcon icon = ...; - items.append(ModelItemInfo(name, type, ModelItemInfo::Method, - QString::fromUtf8(symbol->fileName(), symbol->line()), - symbol->line())); + appendItems(name, type, ModelItemInfo::Method, symbol->fileName()); } return false; } @@ -135,12 +137,11 @@ bool SearchSymbols::visit(Class *symbol) return false; QString name = symbolName(symbol); - QString previousScope = switchScope(name); - QIcon icon = icons.iconForSymbol(symbol); - items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class, - QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), - symbol->line(), - icon)); + QString scopedName = scopedSymbolName(name); + QString previousScope = switchScope(scopedName); + appendItem(separateScope ? name : scopedName, + separateScope ? previousScope : QString(), + ModelItemInfo::Class, symbol); Scope *members = symbol->members(); for (unsigned i = 0; i < members->symbolCount(); ++i) { accept(members->symbolAt(i)); @@ -149,11 +150,22 @@ bool SearchSymbols::visit(Class *symbol) return false; } -QString SearchSymbols::symbolName(const Symbol *symbol) const +QString SearchSymbols::scopedSymbolName(const QString &symbolName) const { QString name = _scope; if (! name.isEmpty()) name += QLatin1String("::"); + name += symbolName; + return name; +} + +QString SearchSymbols::scopedSymbolName(const Symbol *symbol) const +{ + return scopedSymbolName(symbolName(symbol)); +} + +QString SearchSymbols::symbolName(const Symbol *symbol) const +{ QString symbolName = overview.prettyName(symbol->name()); if (symbolName.isEmpty()) { QString type; @@ -176,6 +188,17 @@ QString SearchSymbols::symbolName(const Symbol *symbol) const symbolName += type; symbolName += QLatin1String(">"); } - name += symbolName; - return name; + return symbolName; +} + +void SearchSymbols::appendItem(const QString &name, + const QString &info, + ModelItemInfo::ItemType type, + const Symbol *symbol) +{ + const QIcon icon = icons.iconForSymbol(symbol); + items.append(ModelItemInfo(name, info, type, + QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()), + symbol->line(), + icon)); } diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h index 948f9d78e8..4997e5cf04 100644 --- a/src/plugins/cpptools/searchsymbols.h +++ b/src/plugins/cpptools/searchsymbols.h @@ -44,6 +44,8 @@ #include <QMetaType> #include <QString> +#include <functional> + namespace CppTools { namespace Internal { @@ -90,6 +92,7 @@ public: SearchSymbols(); void setSymbolsToSearchFor(SymbolTypes types); + void setSeparateScope(bool separateScope); QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc) { return operator()(doc, QString()); } @@ -111,14 +114,27 @@ protected: virtual bool visit(CPlusPlus::Declaration *symbol); #endif virtual bool visit(CPlusPlus::Class *symbol); + + QString scopedSymbolName(const QString &symbolName) const; + QString scopedSymbolName(const CPlusPlus::Symbol *symbol) const; QString symbolName(const CPlusPlus::Symbol *symbol) const; + void appendItem(const QString &name, + const QString &info, + ModelItemInfo::ItemType type, + const CPlusPlus::Symbol *symbol); private: + QString findOrInsert(const QString &s) + { return *strings.insert(s); } + + QSet<QString> strings; // Used to avoid QString duplication + QString _scope; CPlusPlus::Overview overview; CPlusPlus::Icons icons; QList<ModelItemInfo> items; SymbolTypes symbolsToSearchFor; + bool separateScope; }; Q_DECLARE_OPERATORS_FOR_FLAGS(SearchSymbols::SymbolTypes) |
