forked from qt-creator/qt-creator
Merge branch '0.9.1-beta' of git@scm.dev.nokia.troll.no:creator/mainline into 0.9.1-beta
Conflicts: src/plugins/qt4projectmanager/qtversionmanager.cpp
This commit is contained in:
@@ -396,11 +396,16 @@ void BookmarkManager::toggleBookmark()
|
||||
if (!editor)
|
||||
return;
|
||||
|
||||
const QFileInfo fi(editor->file()->fileName());
|
||||
const int editorLine = editor->currentLine();
|
||||
toggleBookmark(editor->file()->fileName(), editor->currentLine());
|
||||
}
|
||||
|
||||
void BookmarkManager::toggleBookmark(const QString &fileName, int lineNumber)
|
||||
{
|
||||
const QFileInfo fi(fileName);
|
||||
const int editorLine = lineNumber;
|
||||
|
||||
// Remove any existing bookmark on this line
|
||||
if (Bookmark *mark = findBookmark(fi.path(), fi.fileName(), editorLine)) {
|
||||
if (Bookmark *mark = findBookmark(fi.path(), fi.fileName(), lineNumber)) {
|
||||
// TODO check if the bookmark is really on the same markable Interface
|
||||
removeBookmark(mark);
|
||||
return;
|
||||
|
||||
@@ -34,15 +34,15 @@
|
||||
#ifndef BOOKMARKMANAGER_H
|
||||
#define BOOKMARKMANAGER_H
|
||||
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtGui/QListView>
|
||||
#include <QtCore/QList>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QStyledItemDelegate>
|
||||
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/inavigationwidgetfactory.h>
|
||||
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtCore/QList>
|
||||
#include <QtGui/QListView>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QStyledItemDelegate>
|
||||
|
||||
namespace ProjectExplorer {
|
||||
class SessionManager;
|
||||
}
|
||||
@@ -89,10 +89,16 @@ public:
|
||||
// this QItemSelectionModel is shared by all views
|
||||
QItemSelectionModel *selectionModel() const;
|
||||
|
||||
enum Roles {Filename = Qt::UserRole, LineNumber = Qt::UserRole + 1, Directory = Qt::UserRole + 2, LineText = Qt::UserRole + 3};
|
||||
enum Roles {
|
||||
Filename = Qt::UserRole,
|
||||
LineNumber = Qt::UserRole + 1,
|
||||
Directory = Qt::UserRole + 2,
|
||||
LineText = Qt::UserRole + 3
|
||||
};
|
||||
|
||||
public slots:
|
||||
void toggleBookmark();
|
||||
void toggleBookmark(const QString &fileName, int lineNumber);
|
||||
void nextInDocument();
|
||||
void prevInDocument();
|
||||
void next();
|
||||
@@ -108,6 +114,7 @@ private slots:
|
||||
void updateActionStatus();
|
||||
void gotoBookmark(Bookmark *bookmark);
|
||||
void loadBookmarks();
|
||||
|
||||
private:
|
||||
TextEditor::ITextEditor *currentTextEditor() const;
|
||||
ProjectExplorer::SessionManager* sessionManager() const;
|
||||
@@ -120,8 +127,8 @@ private:
|
||||
static QString bookmarkToString(const Bookmark *b);
|
||||
void saveBookmarks();
|
||||
|
||||
typedef QMultiMap<QString, Bookmark*> FileNameBookmarksMap;
|
||||
typedef QMap<QString, FileNameBookmarksMap*> DirectoryFileBookmarksMap;
|
||||
typedef QMultiMap<QString, Bookmark *> FileNameBookmarksMap;
|
||||
typedef QMap<QString, FileNameBookmarksMap *> DirectoryFileBookmarksMap;
|
||||
|
||||
DirectoryFileBookmarksMap m_bookmarksMap;
|
||||
Core::ICore *m_core;
|
||||
@@ -138,7 +145,7 @@ class BookmarkView : public QListView
|
||||
public:
|
||||
BookmarkView(QWidget *parent = 0);
|
||||
~BookmarkView();
|
||||
void setModel(QAbstractItemModel * model);
|
||||
void setModel(QAbstractItemModel *model);
|
||||
public slots:
|
||||
void gotoBookmark(const QModelIndex &index);
|
||||
protected slots:
|
||||
@@ -146,7 +153,7 @@ protected slots:
|
||||
void removeAll();
|
||||
protected:
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
void removeBookmark(const QModelIndex& index);
|
||||
void removeBookmark(const QModelIndex &index);
|
||||
private:
|
||||
BookmarkContext *m_bookmarkContext;
|
||||
QModelIndex m_contextMenuIndex;
|
||||
|
||||
@@ -36,17 +36,22 @@
|
||||
#include "bookmarks_global.h"
|
||||
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
#include <texteditor/itexteditor.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/uniqueidmanager.h>
|
||||
#include <coreplugin/actionmanager/actionmanagerinterface.h>
|
||||
|
||||
#include <QtCore/qplugin.h>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <QtGui/QMenu>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace Bookmarks::Constants;
|
||||
using namespace Bookmarks::Internal;
|
||||
using namespace TextEditor;
|
||||
|
||||
BookmarksPlugin *BookmarksPlugin::m_instance = 0;
|
||||
|
||||
@@ -159,6 +164,19 @@ bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *)
|
||||
updateActions(m_bookmarkManager->state());
|
||||
addAutoReleasedObject(new BookmarkViewFactory(m_bookmarkManager));
|
||||
|
||||
m_bookmarkMarginAction = new QAction(this);
|
||||
m_bookmarkMarginAction->setText("Toggle Bookmark");
|
||||
//m_bookmarkAction->setIcon(QIcon(":/gdbdebugger/images/breakpoint.svg"));
|
||||
connect(m_bookmarkMarginAction, SIGNAL(triggered()),
|
||||
this, SLOT(bookmarkMarginActionTriggered()));
|
||||
|
||||
// EditorManager
|
||||
QObject *editorManager = m_core->editorManager();
|
||||
connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
|
||||
this, SLOT(editorAboutToClose(Core::IEditor*)));
|
||||
connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
|
||||
this, SLOT(editorOpened(Core::IEditor*)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -169,7 +187,6 @@ BookmarksPlugin::~BookmarksPlugin()
|
||||
|
||||
void BookmarksPlugin::updateActions(int state)
|
||||
{
|
||||
|
||||
const bool hasbm = state >= BookmarkManager::HasBookMarks;
|
||||
const bool hasdocbm = state == BookmarkManager::HasBookmarksInDocument;
|
||||
|
||||
@@ -182,4 +199,32 @@ void BookmarksPlugin::updateActions(int state)
|
||||
m_moveDownAction->setEnabled(hasbm);
|
||||
}
|
||||
|
||||
void BookmarksPlugin::editorOpened(Core::IEditor *editor)
|
||||
{
|
||||
connect(editor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
|
||||
this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
|
||||
}
|
||||
|
||||
void BookmarksPlugin::editorAboutToClose(Core::IEditor *editor)
|
||||
{
|
||||
disconnect(editor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
|
||||
this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
|
||||
}
|
||||
|
||||
void BookmarksPlugin::requestContextMenu(TextEditor::ITextEditor *editor,
|
||||
int lineNumber, QMenu *menu)
|
||||
{
|
||||
m_bookmarkMarginActionLineNumber = lineNumber;
|
||||
m_bookmarkMarginActionFileName = editor->file()->fileName();
|
||||
menu->addAction(m_bookmarkMarginAction);
|
||||
}
|
||||
|
||||
void BookmarksPlugin::bookmarkMarginActionTriggered()
|
||||
{
|
||||
m_bookmarkManager->toggleBookmark(
|
||||
m_bookmarkMarginActionFileName,
|
||||
m_bookmarkMarginActionLineNumber
|
||||
);
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN(BookmarksPlugin)
|
||||
|
||||
@@ -31,18 +31,26 @@
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BOOKMARKS_H
|
||||
#define BOOKMARKS_H
|
||||
#ifndef BOOKMARKSPLUGIN_H
|
||||
#define BOOKMARKSPLUGIN_H
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMultiMap>
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QAction)
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QMenu;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
class ICore;
|
||||
class IEditor;
|
||||
}
|
||||
|
||||
namespace TextEditor {
|
||||
class ITextEditor;
|
||||
}
|
||||
|
||||
namespace Bookmarks {
|
||||
@@ -67,6 +75,13 @@ public:
|
||||
public slots:
|
||||
void updateActions(int stateMask);
|
||||
|
||||
private slots:
|
||||
void editorOpened(Core::IEditor *editor);
|
||||
void editorAboutToClose(Core::IEditor *editor);
|
||||
void requestContextMenu(TextEditor::ITextEditor *editor,
|
||||
int lineNumber, QMenu *menu);
|
||||
void bookmarkMarginActionTriggered();
|
||||
|
||||
private:
|
||||
static BookmarksPlugin *m_instance;
|
||||
BookmarkManager *m_bookmarkManager;
|
||||
@@ -79,6 +94,10 @@ private:
|
||||
QAction *m_docNextAction;
|
||||
QAction *m_moveUpAction;
|
||||
QAction *m_moveDownAction;
|
||||
|
||||
QAction *m_bookmarkMarginAction;
|
||||
int m_bookmarkMarginActionLineNumber;
|
||||
QString m_bookmarkMarginActionFileName;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -64,11 +64,12 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
|
||||
|
||||
CppTools::CppModelManagerInterface *modelmanager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
|
||||
if (modelmanager) {
|
||||
CppTools::CppModelManagerInterface::ProjectInfo *pinfo = modelmanager->projectInfo(this);
|
||||
pinfo->includePaths = cbpparser.includeFiles();
|
||||
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
|
||||
pinfo.includePaths = cbpparser.includeFiles();
|
||||
// TODO we only want C++ files, not all other stuff that might be in the project
|
||||
pinfo->sourceFiles = m_files;
|
||||
pinfo.sourceFiles = m_files;
|
||||
// TODO defines
|
||||
modelmanager->updateProjectInfo(pinfo);
|
||||
}
|
||||
} else {
|
||||
// TODO report error
|
||||
|
||||
@@ -100,4 +100,4 @@ signals:
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif //IEDITOR_H
|
||||
#endif // IEDITOR_H
|
||||
|
||||
@@ -63,7 +63,7 @@ ViewManager::ViewManager(MainWindow *mainWnd) :
|
||||
ViewManagerInterface(mainWnd),
|
||||
m_mainWnd(mainWnd)
|
||||
{
|
||||
for(int i = 0; i< 3; ++i) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
QWidget *w = new QWidget();
|
||||
m_mainWnd->statusBar()->insertPermanentWidget(i, w);
|
||||
w->setLayout(new QHBoxLayout);
|
||||
@@ -89,7 +89,7 @@ void ViewManager::init()
|
||||
|
||||
void ViewManager::objectAdded(QObject *obj)
|
||||
{
|
||||
IView * view = Aggregation::query<IView>(obj);
|
||||
IView *view = Aggregation::query<IView>(obj);
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
@@ -104,8 +104,8 @@ void ViewManager::objectAdded(QObject *obj)
|
||||
|
||||
void ViewManager::aboutToRemoveObject(QObject *obj)
|
||||
{
|
||||
IView * view = Aggregation::query<IView>(obj);
|
||||
if(!view)
|
||||
IView *view = Aggregation::query<IView>(obj);
|
||||
if (!view)
|
||||
return;
|
||||
m_mainWnd->removeContextObject(view);
|
||||
}
|
||||
@@ -121,10 +121,10 @@ void ViewManager::saveSettings(QSettings *settings)
|
||||
settings->setValue(QLatin1String("ViewGroup_Default"), m_mainWnd->saveState());
|
||||
}
|
||||
|
||||
IView * ViewManager::view(const QString & id)
|
||||
IView *ViewManager::view(const QString &id)
|
||||
{
|
||||
QList<IView *> list = m_mainWnd->pluginManager()->getObjects<IView>();
|
||||
foreach (IView * view, list) {
|
||||
foreach (IView *view, list) {
|
||||
if (view->uniqueViewName() == id)
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<plugin name="CodePaster" version="0.1" compatVersion="0.1">
|
||||
<plugin name="CodePaster" version="0.9.1" compatVersion="0.9.1">
|
||||
<vendor>Nokia Corporation</vendor>
|
||||
<copyright>(C) 2008 Nokia Corporation</copyright>
|
||||
<license>Nokia Technology Preview License Agreement</license>
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include <QtGui/QComboBox>
|
||||
#include <QtGui/QTreeView>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QStringListModel>
|
||||
|
||||
using namespace CPlusPlus;
|
||||
using namespace CppEditor::Internal;
|
||||
@@ -202,7 +203,9 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable)
|
||||
m_methodCombo->setMaxVisibleItems(20);
|
||||
|
||||
m_overviewModel = new OverviewModel(this);
|
||||
m_methodCombo->setModel(m_overviewModel);
|
||||
m_noSymbolsModel = new QStringListModel(this);
|
||||
m_noSymbolsModel->setStringList(QStringList() << tr("<no symbols>"));
|
||||
m_methodCombo->setModel(m_noSymbolsModel);
|
||||
|
||||
connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int)));
|
||||
connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex()));
|
||||
@@ -315,9 +318,16 @@ void CPPEditor::onDocumentUpdated(Document::Ptr doc)
|
||||
return;
|
||||
|
||||
m_overviewModel->rebuild(doc);
|
||||
OverviewTreeView *treeView = static_cast<OverviewTreeView *>(m_methodCombo->view());
|
||||
treeView->sync();
|
||||
updateMethodBoxIndex();
|
||||
if (m_overviewModel->rowCount() > 0) {
|
||||
if (m_methodCombo->model() != m_overviewModel)
|
||||
m_methodCombo->setModel(m_overviewModel);
|
||||
OverviewTreeView *treeView = static_cast<OverviewTreeView *>(m_methodCombo->view());
|
||||
treeView->sync();
|
||||
updateMethodBoxIndex();
|
||||
} else {
|
||||
if (m_methodCombo->model() != m_noSymbolsModel)
|
||||
m_methodCombo->setModel(m_noSymbolsModel);
|
||||
}
|
||||
}
|
||||
|
||||
void CPPEditor::updateFileName()
|
||||
@@ -325,6 +335,8 @@ void CPPEditor::updateFileName()
|
||||
|
||||
void CPPEditor::jumpToMethod(int)
|
||||
{
|
||||
if (m_methodCombo->model() != m_overviewModel)
|
||||
return;
|
||||
QModelIndex index = m_methodCombo->view()->currentIndex();
|
||||
Symbol *symbol = m_overviewModel->symbolFromIndex(index);
|
||||
if (! symbol)
|
||||
@@ -339,12 +351,14 @@ void CPPEditor::jumpToMethod(int)
|
||||
|
||||
void CPPEditor::updateMethodBoxIndex()
|
||||
{
|
||||
if (m_methodCombo->model() != m_overviewModel)
|
||||
return;
|
||||
int line = 0, column = 0;
|
||||
convertPosition(position(), &line, &column);
|
||||
|
||||
QModelIndex lastIndex;
|
||||
|
||||
const int rc = m_overviewModel->rowCount(QModelIndex());
|
||||
const int rc = m_overviewModel->rowCount();
|
||||
for (int row = 0; row < rc; ++row) {
|
||||
const QModelIndex index = m_overviewModel->index(row, 0, QModelIndex());
|
||||
Symbol *symbol = m_overviewModel->symbolFromIndex(index);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QComboBox;
|
||||
class QStringListModel;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
@@ -138,6 +139,7 @@ private:
|
||||
QList<int> m_contexts;
|
||||
QComboBox *m_methodCombo;
|
||||
CPlusPlus::OverviewModel *m_overviewModel;
|
||||
QStringListModel *m_noSymbolsModel;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#define _SCL_SECURE_NO_WARNINGS 1
|
||||
#include "pp.h"
|
||||
|
||||
#include "cppmodelmanager.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,328 @@ 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)
|
||||
{ m_workingCopy = workingCopy; }
|
||||
|
||||
void setIncludePaths(const QStringList &includePaths)
|
||||
{ m_includePaths = includePaths; }
|
||||
|
||||
void setFrameworkPaths(const QStringList &frameworkPaths)
|
||||
{ m_frameworkPaths = frameworkPaths; }
|
||||
|
||||
void addIncludePath(const QString &path)
|
||||
{ m_includePaths.append(path); }
|
||||
|
||||
void setProjectFiles(const QStringList &files)
|
||||
{ m_projectFiles = files; }
|
||||
|
||||
void run(QString &fileName)
|
||||
{ sourceNeeded(fileName, IncludeGlobal); }
|
||||
|
||||
void operator()(QString &fileName)
|
||||
{ run(fileName); }
|
||||
void setWorkingCopy(const QMap<QString, QByteArray> &workingCopy);
|
||||
void setIncludePaths(const QStringList &includePaths);
|
||||
void setFrameworkPaths(const QStringList &frameworkPaths);
|
||||
void addIncludePath(const QString &path);
|
||||
void setProjectFiles(const QStringList &files);
|
||||
void run(QString &fileName);
|
||||
void operator()(QString &fileName);
|
||||
|
||||
protected:
|
||||
bool includeFile(const QString &absoluteFilePath, QByteArray *result)
|
||||
{
|
||||
if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) {
|
||||
return true;
|
||||
}
|
||||
CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
|
||||
|
||||
if (m_workingCopy.contains(absoluteFilePath)) {
|
||||
m_included.insert(absoluteFilePath);
|
||||
*result = m_workingCopy.value(absoluteFilePath);
|
||||
return true;
|
||||
}
|
||||
bool includeFile(const QString &absoluteFilePath, QByteArray *result);
|
||||
QByteArray tryIncludeFile(QString &fileName, IncludeType type);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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('/'));
|
||||
|
||||
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;
|
||||
|
||||
m_currentDoc->appendMacro(macroName, macroText);
|
||||
}
|
||||
void mergeEnvironment(CPlusPlus::Document::Ptr doc);
|
||||
void mergeEnvironment(CPlusPlus::Document::Ptr doc, QSet<QString> *processed);
|
||||
|
||||
virtual void macroAdded(const QByteArray ¯oName,
|
||||
const QByteArray ¯oText);
|
||||
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());
|
||||
}
|
||||
|
||||
virtual void stopExpandingMacro(unsigned, const rpp::Macro &)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
//qDebug() << "stop expanding:" << macro.name;
|
||||
}
|
||||
|
||||
void mergeEnvironment(Document::Ptr doc)
|
||||
{
|
||||
QSet<QString> processed;
|
||||
mergeEnvironment(doc, &processed);
|
||||
}
|
||||
|
||||
void mergeEnvironment(Document::Ptr doc, QSet<QString> *processed)
|
||||
{
|
||||
if (! doc)
|
||||
return;
|
||||
|
||||
const QString fn = doc->fileName();
|
||||
|
||||
if (processed->contains(fn))
|
||||
return;
|
||||
|
||||
processed->insert(fn);
|
||||
|
||||
foreach (QString includedFile, doc->includedFiles())
|
||||
mergeEnvironment(m_documents.value(includedFile), processed);
|
||||
|
||||
const QByteArray macros = doc->definedMacros();
|
||||
QByteArray localFileName = doc->fileName().toUtf8();
|
||||
|
||||
QByteArray dummy;
|
||||
m_proc(localFileName, macros, &dummy);
|
||||
}
|
||||
|
||||
virtual void startSkippingBlocks(unsigned offset)
|
||||
{
|
||||
//qDebug() << "start skipping blocks:" << offset;
|
||||
if (m_currentDoc)
|
||||
m_currentDoc->startSkippingBlocks(offset);
|
||||
}
|
||||
|
||||
virtual void stopSkippingBlocks(unsigned offset)
|
||||
{
|
||||
//qDebug() << "stop skipping blocks:" << offset;
|
||||
if (m_currentDoc)
|
||||
m_currentDoc->stopSkippingBlocks(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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(),
|
||||
m_currentDoc->translationUnit()->fileNameLength());
|
||||
|
||||
QByteArray preprocessedCode;
|
||||
m_proc(contents, &preprocessedCode);
|
||||
//qDebug() << preprocessedCode;
|
||||
|
||||
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.
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
rpp::Environment env;
|
||||
rpp::pp m_proc;
|
||||
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;
|
||||
Document::Ptr m_currentDoc;
|
||||
CPlusPlus::Document::Ptr m_currentDoc;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CppTools
|
||||
|
||||
CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager)
|
||||
: m_modelManager(modelManager),
|
||||
m_documents(modelManager->documents()),
|
||||
m_proc(this, env)
|
||||
{ }
|
||||
|
||||
void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)
|
||||
{ m_workingCopy = workingCopy; }
|
||||
|
||||
void CppPreprocessor::setIncludePaths(const QStringList &includePaths)
|
||||
{ m_includePaths = includePaths; }
|
||||
|
||||
void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths)
|
||||
{ m_frameworkPaths = frameworkPaths; }
|
||||
|
||||
void CppPreprocessor::addIncludePath(const QString &path)
|
||||
{ m_includePaths.append(path); }
|
||||
|
||||
void CppPreprocessor::setProjectFiles(const QStringList &files)
|
||||
{ m_projectFiles = files; }
|
||||
|
||||
void CppPreprocessor::run(QString &fileName)
|
||||
{ sourceNeeded(fileName, IncludeGlobal); }
|
||||
|
||||
void CppPreprocessor::operator()(QString &fileName)
|
||||
{ run(fileName); }
|
||||
|
||||
bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QByteArray *result)
|
||||
{
|
||||
if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath)) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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('/'));
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void CppPreprocessor::macroAdded(const QByteArray ¯oName, const QByteArray ¯oText)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
m_currentDoc->appendMacro(macroName, macroText);
|
||||
}
|
||||
|
||||
void CppPreprocessor::startExpandingMacro(unsigned offset,
|
||||
const Macro &,
|
||||
const QByteArray &originalText)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
//qDebug() << "start expanding:" << macro.name << "text:" << originalText;
|
||||
m_currentDoc->addMacroUse(offset, originalText.length());
|
||||
}
|
||||
|
||||
void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &)
|
||||
{
|
||||
if (! m_currentDoc)
|
||||
return;
|
||||
|
||||
//qDebug() << "stop expanding:" << macro.name;
|
||||
}
|
||||
|
||||
void CppPreprocessor::mergeEnvironment(Document::Ptr doc)
|
||||
{
|
||||
QSet<QString> processed;
|
||||
mergeEnvironment(doc, &processed);
|
||||
}
|
||||
|
||||
void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *processed)
|
||||
{
|
||||
if (! doc)
|
||||
return;
|
||||
|
||||
const QString fn = doc->fileName();
|
||||
|
||||
if (processed->contains(fn))
|
||||
return;
|
||||
|
||||
processed->insert(fn);
|
||||
|
||||
foreach (QString includedFile, doc->includedFiles())
|
||||
mergeEnvironment(m_documents.value(includedFile), processed);
|
||||
|
||||
const QByteArray macros = doc->definedMacros();
|
||||
QByteArray localFileName = doc->fileName().toUtf8();
|
||||
|
||||
QByteArray dummy;
|
||||
m_proc(localFileName, macros, &dummy);
|
||||
}
|
||||
|
||||
void CppPreprocessor::startSkippingBlocks(unsigned offset)
|
||||
{
|
||||
//qDebug() << "start skipping blocks:" << offset;
|
||||
if (m_currentDoc)
|
||||
m_currentDoc->startSkippingBlocks(offset);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
const QByteArray previousFile = env.current_file;
|
||||
const unsigned previousLine = env.currentLine;
|
||||
|
||||
env.current_file = QByteArray(m_currentDoc->translationUnit()->fileName(),
|
||||
m_currentDoc->translationUnit()->fileNameLength());
|
||||
|
||||
QByteArray preprocessedCode;
|
||||
m_proc(contents, &preprocessedCode);
|
||||
//qDebug() << preprocessedCode;
|
||||
|
||||
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.
|
||||
|
||||
if (m_modelManager)
|
||||
m_modelManager->emitDocumentUpdated(m_currentDoc);
|
||||
(void) switchDocument(previousDoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,12 +478,25 @@ 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; }
|
||||
|
||||
void CppModelManager::ensureUpdated()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
if (! m_dirty)
|
||||
return;
|
||||
|
||||
m_projectFiles = updateProjectFiles();
|
||||
m_includePaths = updateIncludePaths();
|
||||
m_frameworkPaths = updateFrameworkPaths();
|
||||
m_definedMacros = updateDefinedMacros();
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
QStringList CppModelManager::updateProjectFiles() const
|
||||
{
|
||||
QStringList files;
|
||||
@@ -527,8 +568,29 @@ 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);
|
||||
}
|
||||
|
||||
QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles)
|
||||
{
|
||||
@@ -691,13 +753,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 +772,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,
|
||||
|
||||
@@ -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,22 +132,12 @@ private:
|
||||
return m_definedMacros;
|
||||
}
|
||||
|
||||
void ensureUpdated();
|
||||
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;
|
||||
}
|
||||
|
||||
static void parse(QFutureInterface<void> &future,
|
||||
CppPreprocessor *preproc,
|
||||
QStringList files);
|
||||
@@ -166,6 +161,8 @@ private:
|
||||
// project integration
|
||||
QMap<ProjectExplorer::Project *, ProjectInfo> m_projects;
|
||||
|
||||
mutable QMutex mutex;
|
||||
|
||||
enum {
|
||||
MAX_SELECTION_COUNT = 5
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace CppTools {
|
||||
namespace Internal {
|
||||
|
||||
|
||||
@@ -285,6 +285,7 @@ void DebuggerOutputWindow::showOutput(const QString &prefix, const QString &outp
|
||||
|
||||
void DebuggerOutputWindow::showInput(const QString &prefix, const QString &input)
|
||||
{
|
||||
Q_UNUSED(prefix);
|
||||
m_inputText->append(input);
|
||||
QTextCursor cursor = m_inputText->textCursor();
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
|
||||
@@ -250,6 +250,12 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *error_mes
|
||||
|
||||
m_gdbRunningContext = uidm->uniqueIdentifier(Constants::GDBRUNNING);
|
||||
|
||||
m_breakpointMarginAction = new QAction(this);
|
||||
m_breakpointMarginAction->setText("Toggle Breakpoint");
|
||||
//m_breakpointMarginAction->setIcon(QIcon(":/gdbdebugger/images/breakpoint.svg"));
|
||||
connect(m_breakpointMarginAction, SIGNAL(triggered()),
|
||||
this, SLOT(breakpointMarginActionTriggered()));
|
||||
|
||||
//Core::IActionContainer *mcppcontext =
|
||||
// actionManager->actionContainer(CppEditor::Constants::M_CONTEXT);
|
||||
|
||||
@@ -502,6 +508,8 @@ void DebuggerPlugin::editorOpened(Core::IEditor *editor)
|
||||
this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
|
||||
connect(editor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
|
||||
this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
|
||||
connect(textEditor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
|
||||
this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,9 +520,27 @@ void DebuggerPlugin::editorAboutToClose(Core::IEditor *editor)
|
||||
this, SLOT(requestMark(TextEditor::ITextEditor*,int)));
|
||||
disconnect(editor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*,QPoint,int)),
|
||||
this, SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int)));
|
||||
disconnect(textEditor, SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
|
||||
this, SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
|
||||
}
|
||||
}
|
||||
|
||||
void DebuggerPlugin::requestContextMenu(TextEditor::ITextEditor *editor,
|
||||
int lineNumber, QMenu *menu)
|
||||
{
|
||||
m_breakpointMarginActionLineNumber = lineNumber;
|
||||
m_breakpointMarginActionFileName = editor->file()->fileName();
|
||||
menu->addAction(m_breakpointMarginAction);
|
||||
}
|
||||
|
||||
void DebuggerPlugin::breakpointMarginActionTriggered()
|
||||
{
|
||||
m_manager->toggleBreakpoint(
|
||||
m_breakpointMarginActionFileName,
|
||||
m_breakpointMarginActionLineNumber
|
||||
);
|
||||
}
|
||||
|
||||
void DebuggerPlugin::requestMark(TextEditor::ITextEditor *editor, int lineNumber)
|
||||
{
|
||||
m_manager->toggleBreakpoint(editor->file()->fileName(), lineNumber);
|
||||
|
||||
@@ -84,10 +84,14 @@ private slots:
|
||||
void setSessionValue(const QString &name, const QVariant &value);
|
||||
void queryConfigValue(const QString &name, QVariant *value);
|
||||
void setConfigValue(const QString &name, const QVariant &value);
|
||||
void requestContextMenu(TextEditor::ITextEditor *editor,
|
||||
int lineNumber, QMenu *menu);
|
||||
|
||||
void resetLocation();
|
||||
void gotoLocation(const QString &fileName, int line, bool setMarker);
|
||||
|
||||
void breakpointMarginActionTriggered();
|
||||
|
||||
private:
|
||||
friend class DebuggerManager;
|
||||
friend class DebugMode; // FIXME: Just a hack now so that it can access the views
|
||||
@@ -104,6 +108,10 @@ private:
|
||||
QString m_previousMode;
|
||||
LocationMark *m_locationMark;
|
||||
int m_gdbRunningContext;
|
||||
|
||||
QAction *m_breakpointMarginAction;
|
||||
int m_breakpointMarginActionLineNumber;
|
||||
QString m_breakpointMarginActionFileName;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -1271,6 +1271,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
if (isStoppedReason(reason) || reason.isEmpty()) {
|
||||
// Need another round trip
|
||||
if (reason == "breakpoint-hit") {
|
||||
q->showStatusMessage(tr("Stopped at breakpoint."), -1);
|
||||
GdbMi frame = data.findChild("frame");
|
||||
//qDebug() << frame.toString();
|
||||
m_currentFrame = frame.findChild("addr").data() + '%' +
|
||||
@@ -1282,6 +1283,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
QVariant var = QVariant::fromValue<GdbMi>(data);
|
||||
sendCommand("p 0", GdbAsyncOutput2, var); // dummy
|
||||
} else {
|
||||
q->showStatusMessage(tr("Stopped. %1").arg(reason), -1);
|
||||
handleAsyncOutput2(data);
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -320,6 +320,51 @@ static WatchData take(const QString &iname, QList<WatchData> *list)
|
||||
}
|
||||
|
||||
|
||||
static QList<WatchData> initialSet()
|
||||
{
|
||||
QList<WatchData> result;
|
||||
|
||||
WatchData root;
|
||||
root.state = 0;
|
||||
root.level = 0;
|
||||
root.row = 0;
|
||||
root.name = "Root";
|
||||
root.parentIndex = -1;
|
||||
root.childIndex.append(1);
|
||||
root.childIndex.append(2);
|
||||
root.childIndex.append(3);
|
||||
result.append(root);
|
||||
|
||||
WatchData local;
|
||||
local.iname = "local";
|
||||
local.name = "Locals";
|
||||
local.state = 0;
|
||||
local.level = 1;
|
||||
local.row = 0;
|
||||
local.parentIndex = 0;
|
||||
result.append(local);
|
||||
|
||||
WatchData tooltip;
|
||||
tooltip.iname = "tooltip";
|
||||
tooltip.name = "Tooltip";
|
||||
tooltip.state = 0;
|
||||
tooltip.level = 1;
|
||||
tooltip.row = 1;
|
||||
tooltip.parentIndex = 0;
|
||||
result.append(tooltip);
|
||||
|
||||
WatchData watch;
|
||||
watch.iname = "watch";
|
||||
watch.name = "Watchers";
|
||||
watch.state = 0;
|
||||
watch.level = 1;
|
||||
watch.row = 2;
|
||||
watch.parentIndex = 0;
|
||||
result.append(watch);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WatchHandler
|
||||
@@ -332,7 +377,8 @@ WatchHandler::WatchHandler()
|
||||
m_inFetchMore = false;
|
||||
m_inChange = false;
|
||||
|
||||
cleanModel();
|
||||
m_completeSet = initialSet();
|
||||
m_incompleteSet.clear();
|
||||
m_displaySet = m_completeSet;
|
||||
}
|
||||
|
||||
@@ -380,6 +426,7 @@ QVariant WatchHandler::data(const QModelIndex &idx, int role) const
|
||||
int node = idx.internalId();
|
||||
if (node < 0)
|
||||
return QVariant();
|
||||
QWB_ASSERT(node < m_displaySet.size(), return QVariant());
|
||||
|
||||
const WatchData &data = m_displaySet.at(node);
|
||||
|
||||
@@ -441,6 +488,13 @@ QVariant WatchHandler::data(const QModelIndex &idx, int role) const
|
||||
case VisualRole:
|
||||
return m_displayedINames.contains(data.iname);
|
||||
|
||||
case ExpandedRole:
|
||||
//qDebug() << " FETCHING: " << data.iname
|
||||
// << m_expandedINames.contains(data.iname)
|
||||
// << m_expandedINames;
|
||||
// Level 0 and 1 are always expanded
|
||||
return node < 4 || m_expandedINames.contains(data.iname);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -558,10 +612,13 @@ void WatchHandler::rebuildModel()
|
||||
MODEL_DEBUG("RECREATE MODEL, CURRENT SET:\n" << toString());
|
||||
#endif
|
||||
|
||||
QHash<QString, int> oldTopINames;
|
||||
QHash<QString, QString> oldValues;
|
||||
for (int i = 0, n = m_oldSet.size(); i != n; ++i) {
|
||||
WatchData &data = m_oldSet[i];
|
||||
oldValues[data.iname] = data.value;
|
||||
if (data.level == 2)
|
||||
++oldTopINames[data.iname];
|
||||
}
|
||||
#ifdef DEBUG_PENDING
|
||||
MODEL_DEBUG("OLD VALUES: " << oldValues);
|
||||
@@ -575,6 +632,9 @@ void WatchHandler::rebuildModel()
|
||||
|
||||
qSort(m_completeSet.begin(), m_completeSet.end(), &iNameSorter);
|
||||
|
||||
// This helps to decide whether the view has completely changed or not.
|
||||
QHash<QString, int> topINames;
|
||||
|
||||
QHash<QString, int> iname2idx;
|
||||
|
||||
for (int i = m_completeSet.size(); --i > 0; ) {
|
||||
@@ -582,7 +642,10 @@ void WatchHandler::rebuildModel()
|
||||
data.parentIndex = 0;
|
||||
data.childIndex.clear();
|
||||
iname2idx[data.iname] = i;
|
||||
if (data.level == 2)
|
||||
++topINames[data.iname];
|
||||
}
|
||||
//qDebug() << "TOPINAMES: " << topINames << "\nOLD: " << oldTopINames;
|
||||
|
||||
for (int i = 1; i < m_completeSet.size(); ++i) {
|
||||
WatchData &data = m_completeSet[i];
|
||||
@@ -603,7 +666,13 @@ void WatchHandler::rebuildModel()
|
||||
&& data.value != strNotInScope;
|
||||
}
|
||||
|
||||
//emit layoutAboutToBeChanged();
|
||||
emit layoutAboutToBeChanged();
|
||||
|
||||
if (oldTopINames != topINames) {
|
||||
m_displaySet = initialSet();
|
||||
m_expandedINames.clear();
|
||||
emit reset();
|
||||
}
|
||||
|
||||
m_displaySet = m_completeSet;
|
||||
|
||||
@@ -668,11 +737,6 @@ void WatchHandler::rebuildModel()
|
||||
emit reset();
|
||||
//qDebug() << "WATCHHANDLER: RESET EMITTED";
|
||||
m_inChange = false;
|
||||
//emit layoutChanged();
|
||||
//QSet<QString> einames = m_expandedINames;
|
||||
//einames.insert("local");
|
||||
//einames.insert("watch");
|
||||
//emit expandedItems(einames);
|
||||
|
||||
#if DEBUG_MODEL
|
||||
#if USE_MODEL_TEST
|
||||
@@ -691,8 +755,11 @@ void WatchHandler::cleanup()
|
||||
m_oldSet.clear();
|
||||
m_expandedINames.clear();
|
||||
m_displayedINames.clear();
|
||||
cleanModel();
|
||||
|
||||
m_incompleteSet.clear();
|
||||
m_completeSet = initialSet();
|
||||
m_displaySet = m_completeSet;
|
||||
|
||||
#if 0
|
||||
for (EditWindows::ConstIterator it = m_editWindows.begin();
|
||||
it != m_editWindows.end(); ++it) {
|
||||
@@ -707,7 +774,7 @@ void WatchHandler::cleanup()
|
||||
void WatchHandler::collapseChildren(const QModelIndex &idx)
|
||||
{
|
||||
if (m_inChange || m_completeSet.isEmpty()) {
|
||||
//qDebug() << "WATCHHANDLER: COLLAPSE IGNORED" << idx;
|
||||
qDebug() << "WATCHHANDLER: COLLAPSE IGNORED" << idx;
|
||||
return;
|
||||
}
|
||||
QWB_ASSERT(checkIndex(idx.internalId()), return);
|
||||
@@ -879,56 +946,10 @@ void WatchHandler::removeWatchExpression(const QString &iname)
|
||||
emit watchModelUpdateRequested();
|
||||
}
|
||||
|
||||
void WatchHandler::cleanModel()
|
||||
{
|
||||
// This uses data stored in m_oldSet to re-create a new set
|
||||
// one-by-one
|
||||
m_completeSet.clear();
|
||||
m_incompleteSet.clear();
|
||||
|
||||
WatchData root;
|
||||
root.state = 0;
|
||||
root.level = 0;
|
||||
root.row = 0;
|
||||
root.name = "Root";
|
||||
root.parentIndex = -1;
|
||||
root.childIndex.append(1);
|
||||
root.childIndex.append(2);
|
||||
root.childIndex.append(3);
|
||||
m_completeSet.append(root);
|
||||
|
||||
WatchData local;
|
||||
local.iname = "local";
|
||||
local.name = "Locals";
|
||||
local.state = 0;
|
||||
local.level = 1;
|
||||
local.row = 0;
|
||||
local.parentIndex = 0;
|
||||
m_completeSet.append(local);
|
||||
|
||||
WatchData tooltip;
|
||||
tooltip.iname = "tooltip";
|
||||
tooltip.name = "Tooltip";
|
||||
tooltip.state = 0;
|
||||
tooltip.level = 1;
|
||||
tooltip.row = 1;
|
||||
tooltip.parentIndex = 0;
|
||||
m_completeSet.append(tooltip);
|
||||
|
||||
WatchData watch;
|
||||
watch.iname = "watch";
|
||||
watch.name = "Watchers";
|
||||
watch.state = 0;
|
||||
watch.level = 1;
|
||||
watch.row = 2;
|
||||
watch.parentIndex = 0;
|
||||
m_completeSet.append(watch);
|
||||
}
|
||||
|
||||
|
||||
void WatchHandler::reinitializeWatchers()
|
||||
{
|
||||
cleanModel();
|
||||
m_completeSet = initialSet();
|
||||
m_incompleteSet.clear();
|
||||
|
||||
// copy over all watchers and mark all watchers as incomplete
|
||||
for (int i = 0, n = m_oldSet.size(); i < n; ++i) {
|
||||
|
||||
@@ -135,7 +135,7 @@ public:
|
||||
bool changed;
|
||||
};
|
||||
|
||||
enum { INameRole = Qt::UserRole, VisualRole };
|
||||
enum { INameRole = Qt::UserRole, VisualRole, ExpandedRole };
|
||||
|
||||
|
||||
class WatchHandler : public QAbstractItemModel
|
||||
@@ -192,7 +192,6 @@ signals:
|
||||
private:
|
||||
WatchData takeData(const QString &iname);
|
||||
QString toString() const;
|
||||
void cleanModel();
|
||||
|
||||
bool m_expandPointers;
|
||||
bool m_inChange;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
using namespace Debugger::Internal;
|
||||
|
||||
enum { INameRole = Qt::UserRole, VisualRole };
|
||||
enum { INameRole = Qt::UserRole, VisualRole, ExpandedRole };
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -57,7 +57,6 @@ enum { INameRole = Qt::UserRole, VisualRole };
|
||||
WatchWindow::WatchWindow(Type type, QWidget *parent)
|
||||
: QTreeView(parent), m_type(type)
|
||||
{
|
||||
m_blocked = false;
|
||||
setWindowTitle(tr("Locals and Watchers"));
|
||||
setAlternatingRowColors(true);
|
||||
setIndentation(indentation() * 9/10);
|
||||
@@ -76,12 +75,6 @@ void WatchWindow::expandNode(const QModelIndex &idx)
|
||||
//QModelIndex mi0 = idx.sibling(idx.row(), 0);
|
||||
//QString iname = model()->data(mi0, INameRole).toString();
|
||||
//QString name = model()->data(mi0, Qt::DisplayRole).toString();
|
||||
//qDebug() << "\n\nEXPAND NODE " // << iname << name
|
||||
// << idx << (m_blocked ? "blocked" : "passed");
|
||||
//if (isExpanded(idx))
|
||||
// return;
|
||||
//if (m_blocked)
|
||||
// return;
|
||||
emit requestExpandChildren(idx);
|
||||
}
|
||||
|
||||
@@ -91,8 +84,6 @@ void WatchWindow::collapseNode(const QModelIndex &idx)
|
||||
//QString iname = model()->data(mi0, INameRole).toString();
|
||||
//QString name = model()->data(mi0, Qt::DisplayRole).toString();
|
||||
//qDebug() << "COLLAPSE NODE " << idx;
|
||||
if (m_blocked)
|
||||
return;
|
||||
emit requestCollapseChildren(idx);
|
||||
}
|
||||
|
||||
@@ -181,6 +172,7 @@ void WatchWindow::reset()
|
||||
QTreeView::reset();
|
||||
setRootIndex(model()->index(row, 0, model()->index(0, 0)));
|
||||
//setRootIndex(model()->index(0, 0));
|
||||
resetHelper(model()->index(0, 0));
|
||||
}
|
||||
|
||||
void WatchWindow::setModel(QAbstractItemModel *model)
|
||||
@@ -192,55 +184,15 @@ void WatchWindow::setModel(QAbstractItemModel *model)
|
||||
header()->setResizeMode(QHeaderView::ResizeToContents);
|
||||
if (m_type != LocalsType)
|
||||
header()->hide();
|
||||
|
||||
connect(model, SIGNAL(modelAboutToBeReset()),
|
||||
this, SLOT(modelAboutToBeReset()));
|
||||
connect(model, SIGNAL(modelReset()),
|
||||
this, SLOT(modelReset()));
|
||||
}
|
||||
|
||||
void WatchWindow::modelAboutToBeReset()
|
||||
void WatchWindow::resetHelper(const QModelIndex &idx)
|
||||
{
|
||||
m_blocked = true;
|
||||
//qDebug() << "Model about to be reset";
|
||||
m_expandedItems.clear();
|
||||
m_expandedItems.insert("local");
|
||||
m_expandedItems.insert("watch");
|
||||
modelAboutToBeResetHelper(model()->index(0, 0));
|
||||
//qDebug() << " expanded: " << m_expandedItems;
|
||||
}
|
||||
|
||||
void WatchWindow::modelAboutToBeResetHelper(const QModelIndex &idx)
|
||||
{
|
||||
QString iname = model()->data(idx, INameRole).toString();
|
||||
//qDebug() << "Model about to be reset helper" << iname << idx
|
||||
// << isExpanded(idx);
|
||||
if (isExpanded(idx))
|
||||
m_expandedItems.insert(iname);
|
||||
for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
|
||||
QModelIndex idx1 = model()->index(i, 0, idx);
|
||||
modelAboutToBeResetHelper(idx1);
|
||||
}
|
||||
}
|
||||
|
||||
void WatchWindow::modelReset()
|
||||
{
|
||||
//qDebug() << "Model reset";
|
||||
expand(model()->index(0, 0));
|
||||
modelResetHelper(model()->index(0, 0));
|
||||
m_blocked = false;
|
||||
}
|
||||
|
||||
void WatchWindow::modelResetHelper(const QModelIndex &idx)
|
||||
{
|
||||
QString name = model()->data(idx, Qt::DisplayRole).toString();
|
||||
QString iname = model()->data(idx, INameRole).toString();
|
||||
//qDebug() << "Model reset helper" << iname << name;
|
||||
if (m_expandedItems.contains(iname)) {
|
||||
if (model()->data(idx, ExpandedRole).toBool()) {
|
||||
expand(idx);
|
||||
for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
|
||||
QModelIndex idx1 = model()->index(i, 0, idx);
|
||||
modelResetHelper(idx1);
|
||||
resetHelper(idx1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,21 +72,16 @@ private slots:
|
||||
void handleChangedItem(QWidget *);
|
||||
void expandNode(const QModelIndex &index);
|
||||
void collapseNode(const QModelIndex &index);
|
||||
void modelAboutToBeReset();
|
||||
void modelReset();
|
||||
|
||||
private:
|
||||
void contextMenuEvent(QContextMenuEvent *ev);
|
||||
void editItem(const QModelIndex &idx);
|
||||
void reset(); /* reimpl */
|
||||
|
||||
void modelAboutToBeResetHelper(const QModelIndex &idx);
|
||||
void modelResetHelper(const QModelIndex &idx);
|
||||
void resetHelper(const QModelIndex &idx);
|
||||
|
||||
bool m_alwaysResizeColumnsToContents;
|
||||
Type m_type;
|
||||
bool m_blocked;
|
||||
QSet<QString> m_expandedItems;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<plugin name="ScmGit" version="0.1" compatVersion="0.1">
|
||||
<plugin name="ScmGit" version="0.9.1" compatVersion="0.9.1">
|
||||
<vendor>Nokia Corporation</vendor>
|
||||
<copyright>(C) 2008 Nokia Corporation</copyright>
|
||||
<license>Nokia Technology Preview License Agreement</license>
|
||||
|
||||
@@ -39,18 +39,20 @@
|
||||
#include <QtGui/QFileDialog>
|
||||
|
||||
using namespace Perforce::Internal;
|
||||
using namespace Core::Utils;
|
||||
|
||||
SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browseForCommand()));
|
||||
m_ui.pathChooser->setPromptDialogTitle(tr("Perforce Command"));
|
||||
m_ui.pathChooser->setExpectedKind(PathChooser::Command);
|
||||
}
|
||||
|
||||
PerforceSettings SettingsPageWidget::settings() const
|
||||
{
|
||||
PerforceSettings rc;
|
||||
rc.p4Command = m_ui.p4CmdLineEdit->text();
|
||||
rc.p4Command = m_ui.pathChooser->path();
|
||||
rc.defaultEnv = m_ui.defaultCheckBox->isChecked();
|
||||
rc.p4Port = m_ui.portLineEdit->text();
|
||||
rc.p4Client = m_ui.clientLineEdit->text();
|
||||
@@ -60,21 +62,13 @@ PerforceSettings SettingsPageWidget::settings() const
|
||||
|
||||
void SettingsPageWidget::setSettings(const PerforceSettings &s)
|
||||
{
|
||||
m_ui.p4CmdLineEdit->setText(s.p4Command);
|
||||
m_ui.pathChooser->setPath(s.p4Command);
|
||||
m_ui.defaultCheckBox->setChecked(s.defaultEnv);
|
||||
m_ui.portLineEdit->setText(s.p4Port);
|
||||
m_ui.clientLineEdit->setText(s.p4Client);
|
||||
m_ui.userLineEdit->setText(s.p4User);
|
||||
}
|
||||
|
||||
void SettingsPageWidget::browseForCommand()
|
||||
{
|
||||
const QString cmd = QFileDialog::getOpenFileName(window(), tr("Perforce Command"));
|
||||
if (!cmd.isEmpty())
|
||||
m_ui.p4CmdLineEdit->setText(cmd);
|
||||
}
|
||||
|
||||
|
||||
SettingsPage::SettingsPage()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -54,9 +54,6 @@ public:
|
||||
PerforceSettings settings() const;
|
||||
void setSettings(const PerforceSettings &);
|
||||
|
||||
private slots:;
|
||||
void browseForCommand();
|
||||
|
||||
private:
|
||||
Ui::SettingsPage m_ui;
|
||||
};
|
||||
|
||||
@@ -36,14 +36,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="p4CmdLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="browseButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@@ -120,11 +113,18 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Core::Utils::PathChooser</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">utils/pathchooser.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>portLineEdit</tabstop>
|
||||
<tabstop>clientLineEdit</tabstop>
|
||||
<tabstop>userLineEdit</tabstop>
|
||||
<tabstop>p4CmdLineEdit</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
|
||||
@@ -483,23 +483,27 @@ void Qt4Project::updateCodeModel()
|
||||
files += m_projectFiles->files[SourceType];
|
||||
files += m_projectFiles->generatedFiles[SourceType];
|
||||
|
||||
CppTools::CppModelManagerInterface::ProjectInfo *pinfo = modelmanager->projectInfo(this);
|
||||
CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelmanager->projectInfo(this);
|
||||
|
||||
if (pinfo->defines == predefinedMacros &&
|
||||
pinfo->includePaths == allIncludePaths &&
|
||||
pinfo->frameworkPaths == allFrameworkPaths &&
|
||||
pinfo->sourceFiles == files) {
|
||||
// Nothing to update...
|
||||
if (pinfo.defines == predefinedMacros &&
|
||||
pinfo.includePaths == allIncludePaths &&
|
||||
pinfo.frameworkPaths == allFrameworkPaths &&
|
||||
pinfo.sourceFiles == files) {
|
||||
modelmanager->updateProjectInfo(pinfo);
|
||||
} else {
|
||||
pinfo->defines = predefinedMacros;
|
||||
pinfo.defines = predefinedMacros;
|
||||
// pinfo->defines += definedMacros; // ### FIXME: me
|
||||
pinfo->includePaths = allIncludePaths;
|
||||
pinfo->frameworkPaths = allFrameworkPaths;
|
||||
pinfo->sourceFiles = files;
|
||||
pinfo.includePaths = allIncludePaths;
|
||||
pinfo.frameworkPaths = allFrameworkPaths;
|
||||
pinfo.sourceFiles = files;
|
||||
|
||||
modelmanager->updateProjectInfo(pinfo);
|
||||
|
||||
modelmanager->GC();
|
||||
modelmanager->updateSourceFiles(pinfo->sourceFiles);
|
||||
modelmanager->updateSourceFiles(pinfo.sourceFiles);
|
||||
}
|
||||
|
||||
// update info
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -969,7 +969,7 @@ void QtVersion::updateVersionInfo() const
|
||||
QString line = stream.readLine();
|
||||
int index = line.indexOf(":");
|
||||
if (index != -1)
|
||||
m_versionInfo.insert(line.left(index), line.mid(index+1));
|
||||
m_versionInfo.insert(line.left(index), QDir::fromNativeSeparators(line.mid(index+1)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,6 +1041,7 @@ void QtVersion::updateMkSpec() const
|
||||
// mkspec = mkspec.mid(QString("$$QT_BUILD_TREE/mkspecs/").length());
|
||||
// else if (mkspec.startsWith("$$QT_BUILD_TREE\\mkspecs\\"))
|
||||
// mkspec = mkspec.mid(QString("$$QT_BUILD_TREE\\mkspecs\\").length());
|
||||
// mkspec = QDir::fromNativeSeparators(mkspec);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
@@ -1107,7 +1108,8 @@ void QtVersion::updateMkSpec() const
|
||||
int index = mkspec.lastIndexOf('/');
|
||||
if(index == -1)
|
||||
index = mkspec.lastIndexOf('\\');
|
||||
if (index >= 0 && QDir(mkspec.left(index)).canonicalPath() == QDir(m_path + "/mkspecs/").canonicalPath())
|
||||
QString mkspecDir = QDir(m_path + "/mkspecs/").canonicalPath();
|
||||
if (index >= 0 && QDir(mkspec.left(index)).canonicalPath() == mkspecDir)
|
||||
mkspec = mkspec.mid(index+1).trimmed();
|
||||
|
||||
m_mkspec = mkspec;
|
||||
@@ -1119,7 +1121,7 @@ QString QtVersion::makeCommand() const
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
const QString &spec = mkspec();
|
||||
if (spec.startsWith("win32-msvc") || spec == QLatin1String("win32-icc"))
|
||||
if (spec.contains("win32-msvc") || spec.contains(QLatin1String("win32-icc")))
|
||||
return "nmake.exe";
|
||||
else if(spec.startsWith("wince"))
|
||||
return "nmake.exe";
|
||||
@@ -1156,7 +1158,7 @@ QtVersion::ToolchainType QtVersion::toolchainType() const
|
||||
if (!isValid())
|
||||
return INVALID;
|
||||
const QString &spec = mkspec();
|
||||
if(spec.startsWith("win32-msvc") || spec == QLatin1String("win32-icc"))
|
||||
if(spec.contains("win32-msvc") || spec.contains(QLatin1String("win32-icc")))
|
||||
return MSVC;
|
||||
else if(spec == "win32-g++")
|
||||
return MinGW;
|
||||
|
||||
@@ -39,20 +39,24 @@
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
using namespace Subversion::Internal;
|
||||
using namespace Core::Utils;
|
||||
|
||||
|
||||
SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browseForCommand()));
|
||||
m_ui.pathChooser->setExpectedKind(PathChooser::Command);
|
||||
m_ui.pathChooser->setPromptDialogTitle(tr("Subversion Command"));
|
||||
}
|
||||
|
||||
SubversionSettings SettingsPageWidget::settings() const
|
||||
{
|
||||
SubversionSettings rc;
|
||||
rc.svnCommand = m_ui.svnCmdLineEdit->text();
|
||||
rc.svnCommand = m_ui.pathChooser->path();
|
||||
rc.useAuthentication = m_ui.userGroupBox->isChecked();
|
||||
rc.user = m_ui.usernameLineEdit->text();
|
||||
rc.password = m_ui.passwordLineEdit->text();
|
||||
@@ -63,19 +67,12 @@ SubversionSettings SettingsPageWidget::settings() const
|
||||
|
||||
void SettingsPageWidget::setSettings(const SubversionSettings &s)
|
||||
{
|
||||
m_ui.svnCmdLineEdit->setText(s.svnCommand);
|
||||
m_ui.pathChooser->setPath(s.svnCommand);
|
||||
m_ui.usernameLineEdit->setText(s.user);
|
||||
m_ui.passwordLineEdit->setText(s.password);
|
||||
m_ui.userGroupBox->setChecked(s.useAuthentication);
|
||||
}
|
||||
|
||||
void SettingsPageWidget::browseForCommand()
|
||||
{
|
||||
QString cmd = QFileDialog::getOpenFileName(window(), tr("Subversion Command"));
|
||||
if (!cmd.isEmpty())
|
||||
m_ui.svnCmdLineEdit->setText(cmd);
|
||||
}
|
||||
|
||||
SettingsPage::SettingsPage()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -59,9 +59,6 @@ public:
|
||||
SubversionSettings settings() const;
|
||||
void setSettings(const SubversionSettings &);
|
||||
|
||||
private slots:;
|
||||
void browseForCommand();
|
||||
|
||||
private:
|
||||
Ui::SettingsPage m_ui;
|
||||
};
|
||||
|
||||
@@ -32,14 +32,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="svnCmdLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="browseButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@@ -109,9 +102,14 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>svnCmdLineEdit</tabstop>
|
||||
</tabstops>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Core::Utils::PathChooser</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">utils/pathchooser.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -602,29 +602,44 @@ void BaseTextEditor::slotSelectionChanged()
|
||||
void BaseTextEditor::gotoBlockStart()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false))
|
||||
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false)) {
|
||||
setTextCursor(cursor);
|
||||
_q_matchParentheses();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseTextEditor::gotoBlockEnd()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
if (TextBlockUserData::findNextClosingParenthesis(&cursor, false))
|
||||
if (TextBlockUserData::findNextClosingParenthesis(&cursor, false)) {
|
||||
setTextCursor(cursor);
|
||||
_q_matchParentheses();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseTextEditor::gotoBlockStartWithSelection()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true))
|
||||
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true)) {
|
||||
setTextCursor(cursor);
|
||||
_q_matchParentheses();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseTextEditor::gotoBlockEndWithSelection()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
if (TextBlockUserData::findNextClosingParenthesis(&cursor, true))
|
||||
if (TextBlockUserData::findNextClosingParenthesis(&cursor, true)) {
|
||||
setTextCursor(cursor);
|
||||
_q_matchParentheses();
|
||||
}
|
||||
}
|
||||
|
||||
static QTextCursor flippedCursor(const QTextCursor &cursor) {
|
||||
QTextCursor flipped = cursor;
|
||||
flipped.clearSelection();
|
||||
flipped.setPosition(cursor.anchor(), QTextCursor::KeepAnchor);
|
||||
return flipped;
|
||||
}
|
||||
|
||||
void BaseTextEditor::selectBlockUp()
|
||||
@@ -640,7 +655,8 @@ void BaseTextEditor::selectBlockUp()
|
||||
return;
|
||||
if (!TextBlockUserData::findNextClosingParenthesis(&cursor, true))
|
||||
return;
|
||||
setTextCursor(cursor);
|
||||
setTextCursor(flippedCursor(cursor));
|
||||
_q_matchParentheses();
|
||||
}
|
||||
|
||||
void BaseTextEditor::selectBlockDown()
|
||||
@@ -663,7 +679,8 @@ void BaseTextEditor::selectBlockDown()
|
||||
if ( cursor != d->m_selectBlockAnchor)
|
||||
TextBlockUserData::findNextClosingParenthesis(&cursor, true);
|
||||
|
||||
setTextCursor(cursor);
|
||||
setTextCursor(flippedCursor(cursor));
|
||||
_q_matchParentheses();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user