work save: parser - preprocessor
This commit is contained in:
parent
3a019a7180
commit
f0a0ae44b7
|
@ -4,3 +4,25 @@ CppPreprocessor::CppPreprocessor(QObject *parent) : QObject(parent)
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
void CppPreprocessor::addDefinesInFile(const QString &fileName)
|
||||
{
|
||||
if (mProcessed.contains(fileName))
|
||||
return;
|
||||
mProcessed.insert(fileName);
|
||||
// if FastIndexOf(fScannedFiles, FileName) = -1 then
|
||||
// Exit;
|
||||
PDefineMap defineList = mFileDefines.value(fileName, PDefineMap());
|
||||
|
||||
if (defineList) {
|
||||
for (PDefine define: defineList->values()) {
|
||||
mDefines.insert(define->name,define);
|
||||
}
|
||||
}
|
||||
PFileIncludes fileIncludes = getFileIncludesEntry(fileName);
|
||||
if (fileIncludes) {
|
||||
for (QString s:fileIncludes->includeFiles.keys()) {
|
||||
addDefinesInFile(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,72 @@
|
|||
#define CPPPREPROCESSOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTextStream>
|
||||
#include "utils.h"
|
||||
|
||||
struct ParsedFile {
|
||||
int index; // 0-based for programming convenience
|
||||
QString fileName; // Record filename, but not used now
|
||||
QStringList buffer; // do not concat them all
|
||||
int branches; //branch levels;
|
||||
PFileIncludes fileIncludes; // includes of this file
|
||||
};
|
||||
using PParsedFile = std::shared_ptr<ParsedFile>;
|
||||
|
||||
class CppPreprocessor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit CppPreprocessor(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
void preprocessBuffer();
|
||||
void skipToEndOfPreprocessor();
|
||||
void skipToPreprocessor();
|
||||
QString getNextPreprocessor();
|
||||
void simplify(QString& output);
|
||||
void handlePreprocessor(const QString& value);
|
||||
void handleDefine(const QString& line);
|
||||
void handleUndefine(const QString& line);
|
||||
void handleBranch(const QString& line);
|
||||
void handleInclude(const QString& line);
|
||||
QString expandMacros(const QString& line, int depth);
|
||||
QString removeGCCAttributes(const QString& line);
|
||||
QString removeSuffixes(const QString& input);
|
||||
// current file stuff
|
||||
PParsedFile getInclude(int index);
|
||||
void openInclude(const QString& fileName, QTextStream stream = QTextStream());
|
||||
|
||||
void closeInclude();
|
||||
// branch stuff
|
||||
bool getCurrentBranch();
|
||||
void setCurrentBranch(bool value);
|
||||
void removeCurrentBranch();
|
||||
QString getResult();
|
||||
// include stuff
|
||||
PFileIncludes getFileIncludesEntry(const QString& FileName);
|
||||
void addDefinesInFile(const QString& fileName);
|
||||
private:
|
||||
int mIndex; // points to current file buffer. do not free
|
||||
QString mFileName; // idem
|
||||
QStringList mBuffer; // idem
|
||||
QStringList mResult;
|
||||
PFileIncludes mCurrentIncludes;
|
||||
int mPreProcIndex;
|
||||
QStringList mIncludesList;
|
||||
DefineMap mHardDefines; // set by "cpp -dM -E -xc NUL"
|
||||
DefineMap mDefines; // working set, editable
|
||||
QHash<QString, PDefineMap> mFileDefines; //dictionary to save defines for each headerfile;
|
||||
QList<PParsedFile> mIncludes; // stack of files we've stepped into. last one is current file, first one is source file
|
||||
QList<bool> fBranchResults;// stack of branch results (boolean). last one is current branch, first one is outermost branch
|
||||
QStringList mIncludePaths; // path to include folders
|
||||
QStringList mProjectIncludePaths;
|
||||
bool mParseSystem;
|
||||
bool mParseLocal;
|
||||
QSet<QString> mProcessed; // dictionary to save filename already processed
|
||||
};
|
||||
|
||||
#endif // CPPPREPROCESSOR_H
|
||||
|
|
|
@ -3,8 +3,35 @@
|
|||
StatementModel::StatementModel(QObject *parent) : QObject(parent)
|
||||
{
|
||||
mCount = 0;
|
||||
mClearing = false;
|
||||
mBatchDeleteCount = 0;
|
||||
}
|
||||
|
||||
void StatementModel::add(PStatement statement)
|
||||
{
|
||||
if (!statement) {
|
||||
return ;
|
||||
}
|
||||
PStatement parent = statement->parentScope.lock();
|
||||
if (parent) {
|
||||
addMember(parent->children,statement);
|
||||
} else {
|
||||
addMember(mGlobalStatements,statement);
|
||||
}
|
||||
mCount++;
|
||||
}
|
||||
|
||||
void StatementModel::deleteStatement(PStatement statement)
|
||||
{
|
||||
if (!statement) {
|
||||
return ;
|
||||
}
|
||||
PStatement parent = statement->parentScope.lock();
|
||||
int count = 0;
|
||||
if (parent) {
|
||||
count = deleteMember(parent->children,statement);
|
||||
} else {
|
||||
count = deleteMember(mGlobalStatements,statement);
|
||||
}
|
||||
mCount -= count;
|
||||
}
|
||||
|
||||
const StatementMap &StatementModel::childrenStatements(PStatement statement)
|
||||
|
@ -21,3 +48,31 @@ const StatementMap &StatementModel::childrenStatements(std::weak_ptr<Statement>
|
|||
PStatement s = statement.lock();
|
||||
return childrenStatements(s);
|
||||
}
|
||||
|
||||
void StatementModel::clear() {
|
||||
mCount=0;
|
||||
mGlobalStatements.clear();
|
||||
}
|
||||
|
||||
void StatementModel::addMember(StatementMap &map, PStatement statement)
|
||||
{
|
||||
if (!statement)
|
||||
return ;
|
||||
PStatementList lst = map.value(statement->command, PStatementList());
|
||||
if (!lst) {
|
||||
lst=std::make_shared<StatementList>();
|
||||
map.insert(statement->command,lst);
|
||||
}
|
||||
lst->append(statement);
|
||||
}
|
||||
|
||||
int StatementModel::deleteMember(StatementMap &map, PStatement statement)
|
||||
{
|
||||
if (!statement)
|
||||
return 0;
|
||||
PStatementList lst = map.value(statement->command, PStatementList());
|
||||
if (!lst) {
|
||||
return 0;
|
||||
}
|
||||
return lst->removeAll(statement);
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@ public:
|
|||
void add(PStatement statement);
|
||||
// function DeleteFirst: Integer;
|
||||
// function DeleteLast: Integer;
|
||||
void BeginBatchDelete();
|
||||
void endBatchDelete();
|
||||
void deleteStatement(PStatement statement);
|
||||
const StatementMap& childrenStatements(PStatement statement = PStatement());
|
||||
const StatementMap& childrenStatements(std::weak_ptr<Statement> statement);
|
||||
|
@ -23,11 +21,13 @@ public:
|
|||
void dumpWithScope(const QString& logFile);
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
void addMember(StatementMap& map, PStatement statement);
|
||||
int deleteMember(StatementMap& map, PStatement statement);
|
||||
private:
|
||||
int mCount;
|
||||
bool mClearing;
|
||||
StatementMap mGlobalStatements; //may have overloaded functions, so use PStatementList to store
|
||||
int mBatchDeleteCount;
|
||||
};
|
||||
|
||||
#endif // STATEMENTMODEL_H
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <memory>
|
||||
// preprocess/ macro define
|
||||
struct Define {
|
||||
QString Name;
|
||||
QString name;
|
||||
QString args;
|
||||
QString value;
|
||||
QString filename;
|
||||
|
@ -18,6 +18,9 @@ struct Define {
|
|||
|
||||
using PDefine = std::shared_ptr<Define>;
|
||||
|
||||
using DefineMap = QHash<QString,PDefine>;
|
||||
using PDefineMap = std::shared_ptr<DefineMap>;
|
||||
|
||||
enum class SkipType {
|
||||
skItself, // skip itself
|
||||
skToSemicolon, // skip to ;
|
||||
|
@ -88,7 +91,7 @@ struct Statement;
|
|||
using PStatement = std::shared_ptr<Statement>;
|
||||
using StatementList = QVector<PStatement>;
|
||||
using PStatementList = std::shared_ptr<StatementList>;
|
||||
using StatementMap = QMap<QString, PStatementList>;
|
||||
using StatementMap = QHash<QString, PStatementList>;
|
||||
struct Statement {
|
||||
std::weak_ptr<Statement> parentScope; // parent class/struct/namespace scope, don't use auto pointer to prevent circular reference
|
||||
QString hintText; // text to force display when using PrettyPrintStatement
|
||||
|
|
|
@ -613,6 +613,7 @@ public:
|
|||
void saveValue(const QString &key, const QVariant &value);
|
||||
QVariant value(const QString& group, const QString &key, const QVariant& defaultValue);
|
||||
QVariant value(const QString &key, const QVariant& defaultValue);
|
||||
void load();
|
||||
|
||||
Dirs& dirs();
|
||||
Editor& editor();
|
||||
|
|
Loading…
Reference in New Issue