work save: parser - preprocessor

This commit is contained in:
royqh1979@gmail.com 2021-08-07 18:02:57 +08:00
parent 3a019a7180
commit f0a0ae44b7
6 changed files with 146 additions and 8 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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