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:
dt
2008-12-08 12:47:15 +01:00
55 changed files with 972 additions and 638 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -100,4 +100,4 @@ signals:
} // namespace Core
#endif //IEDITOR_H
#endif // IEDITOR_H

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 &macroName, const QByteArray &macroText)
{
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 &macroName,
const QByteArray &macroText);
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 &macro,
const QByteArray &originalText);
virtual void stopExpandingMacro(unsigned offset, const Macro &macro);
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 &macroName, const QByteArray &macroText)
{
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,

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 &macroId, const QByteArray &text) = 0;
virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature.
virtual void startExpandingMacro(unsigned offset,
const Macro &macro,
const QByteArray &originalTextt) = 0;
virtual void stopExpandingMacro(unsigned offset,
const Macro &macro) = 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

View File

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

View File

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

View File

@@ -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 &macro);
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -44,6 +44,8 @@
#include <QMetaType>
#include <QString>
#include <functional>
namespace CppTools {
namespace Internal {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -54,9 +54,6 @@ public:
PerforceSettings settings() const;
void setSettings(const PerforceSettings &);
private slots:;
void browseForCommand();
private:
Ui::SettingsPage m_ui;
};

View File

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

View File

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

View File

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

View File

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

View File

@@ -59,9 +59,6 @@ public:
SubversionSettings settings() const;
void setSettings(const SubversionSettings &);
private slots:;
void browseForCommand();
private:
Ui::SettingsPage m_ui;
};

View File

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

View File

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