work save

This commit is contained in:
royqh1979@gmail.com 2021-08-08 17:22:37 +08:00
parent f9c3fb8dd5
commit 91a63648d5
6 changed files with 214 additions and 12 deletions

View File

@ -1,10 +1,119 @@
#include "cpppreprocessor.h"
#include "../utils.h"
CppPreprocessor::CppPreprocessor(QObject *parent) : QObject(parent)
{
}
QString CppPreprocessor::getNextPreprocessor()
{
skipToPreprocessor(); // skip until # at start of line
int preProcFrom = mIndex;
if (preProcFrom >= mBuffer.count())
return ""; // we've gone past the final #preprocessor line. Yay
skipToEndOfPreprocessor();
int preProcTo = mIndex;
// Calculate index to insert defines in in result file
mPreProcIndex = (mResult.count() - 1) + 1; // offset by one for #include rootfile
// Assemble whole line, including newlines
QString result;
for (int i=preProcFrom;i<=preProcTo;i++) {
result+=mBuffer[i]+'\n';
mResult.append("");// defines resolve into empty files, except #define and #include
}
// Step over
mIndex++;
return result;
}
void CppPreprocessor::handleBranch(const QString &line)
{
if (line.startsWith("ifdef")) {
// if a branch that is not at our level is false, current branch is false too;
for (int i=0;i<=mBranchResults.count()-2;i++) {
if (!mBranchResults[i]) {
setCurrentBranch(false);
return;
}
}
if (!getCurrentBranch()) {
setCurrentBranch(false);
} else {
constexpr int IFDEF_LEN = 5; //length of ifdef;
QString name = line.mid(IFDEF_LEN+1);
int dummy;
setCurrentBranch( getDefine(name,dummy)!=nullptr );
}
}
// if not GetCurrentBranch then // we are already inside an if that is NOT being taken
// SetCurrentBranch(false) // so don't take this one either
// else begin
// Name := TrimLeft(Copy(Line, Length('ifdef') + 1, MaxInt));
// SetCurrentBranch(Assigned(GetDefine(Name,Dummy)));
// end;
// end else if StartsStr('ifndef', Line) then begin
// // if a branch that is not at our level is false, current branch is false too;
// for I := 0 to fBranchResults.Count - 2 do
// if integer(fBranchResults[i]) = 0 then begin
// SetCurrentBranch(false);
// Exit;
// end;
// if not GetCurrentBranch then // we are already inside an if that is NOT being taken
// SetCurrentBranch(false) // so don't take this one either
// else begin
// Name := TrimLeft(Copy(Line, Length('ifndef') + 1, MaxInt));
// SetCurrentBranch(not Assigned(GetDefine(Name,Dummy)));
// end;
// end else if StartsStr('if', Line) then begin
// // if a branch that is not at our level is false, current branch is false too;
// for I := 0 to fBranchResults.Count - 2 do
// if integer(fBranchResults[i]) = 0 then begin
// SetCurrentBranch(false);
// Exit;
// end;
// if not GetCurrentBranch then // we are already inside an if that is NOT being taken
// SetCurrentBranch(false) // so don't take this one either
// else begin
// IfLine := TrimLeft(Copy(Line, Length('if') + 1, MaxInt)); // remove if
// testResult := EvaluateIf(IfLine);
// SetCurrentBranch(testResult);
// end;
// end else if StartsStr('else', Line) then begin
// // if a branch that is not at our level is false, current branch is false too;
// for I := 0 to fBranchResults.Count - 2 do
// if integer(fBranchResults[i]) = 0 then begin
// RemoveCurrentBranch;
// SetCurrentBranch(false);
// Exit;
// end;
// OldResult := GetCurrentBranch; // take either if or else
// RemoveCurrentBranch;
// SetCurrentBranch(not OldResult);
// end else if StartsStr('elif', Line) then begin
// // if a branch that is not at our level is false, current branch is false too;
// for I := 0 to fBranchResults.Count - 2 do
// if integer(fBranchResults[i]) = 0 then begin
// RemoveCurrentBranch;
// SetCurrentBranch(false);
// Exit;
// end;
// OldResult := GetCurrentBranch; // take either if or else
// RemoveCurrentBranch;
// if OldResult then begin // don't take this one, previous if has been taken
// SetCurrentBranch(false);
// end else begin // previous ifs failed. try this one
// IfLine := TrimLeft(Copy(Line, Length('elif') + 1, MaxInt)); // remove elif
// SetCurrentBranch(EvaluateIf(IfLine));
// end;
// end else if StartsStr('endif', Line) then
// RemoveCurrentBranch;
}
QString CppPreprocessor::expandMacros(const QString &line, int depth)
{
//prevent infinit recursion
@ -105,6 +214,11 @@ void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString
}
}
PParsedFile CppPreprocessor::getInclude(int index)
{
return mIncludes[index];
}
void CppPreprocessor::closeInclude()
{
if (mIncludes.isEmpty())
@ -135,13 +249,39 @@ void CppPreprocessor::closeInclude()
.arg(parsedFile->index+1));
}
bool CppPreprocessor::getCurrentBranch()
{
if (!mBranchResults.isEmpty())
return mBranchResults.last();
else
return true;
}
QString CppPreprocessor::getResult()
{
QString s;
for (QString line:mResult) {
s.append(line);
s.append(lineBreak());
}
return s;
}
PFileIncludes CppPreprocessor::getFileIncludesEntry(const QString &fileName)
{
return mIncludesList.value(fileName,PFileIncludes());
}
void CppPreprocessor::addDefinesInFile(const QString &fileName)
{
if (mProcessed.contains(fileName))
return;
mProcessed.insert(fileName);
// if FastIndexOf(fScannedFiles, FileName) = -1 then
// Exit;
//todo: why test this?
if (!mScannedFiles.contains(fileName))
return;
PDefineMap defineList = mFileDefines.value(fileName, PDefineMap());
if (defineList) {
@ -164,3 +304,8 @@ bool CppPreprocessor::isIdentChar(const QChar &ch)
}
return false;
}
QString CppPreprocessor::lineBreak()
{
return "\n";
}

View File

@ -20,7 +20,23 @@ class CppPreprocessor : public QObject
public:
explicit CppPreprocessor(QObject *parent = nullptr);
void clear();
void addDefineByParts(const QString& name, const QString& args,
const QString& value, bool hardCoded);
void getDefineParts(const QString& Input, QString &name, QString &args, QString &value);
void addDefineByLine(const QString& line, bool hardCoded);
PDefine getDefine(const QString& name, int &index);
PDefine getHardDefine(const QString& name, int &index);
void reset(); //reset but don't clear generated defines
void resetDefines();
void setScanOptions(bool parseSystem, bool parseLocal);
void setIncludePaths(QStringList &list);
void setProjectIncludePaths(QStringList& list);
void setScannedFileList(QStringList &list);
void setIncludesList(QString& list);
void preprocessStream(const QString& fileName, QTextStream stream = QTextStream());
void preprocessFile(const QString& fileName);
void invalidDefinesInFile(const QString& fileName);
signals:
private:
@ -29,11 +45,11 @@ private:
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 handleDefine(const QString& line);
void handleInclude(const QString& line);
void handlePreprocessor(const QString& value);
void handleUndefine(const QString& line);
QString expandMacros(const QString& line, int depth);
void expandMacro(const QString& line, QString& newLine, QString& word, int& i, int depth);
QString removeGCCAttributes(const QString& line);
@ -53,6 +69,8 @@ private:
void addDefinesInFile(const QString& fileName);
bool isIdentChar(const QChar& ch);
QString lineBreak();
private:
int mIndex; // points to current file buffer. do not free
QString mFileName; // idem
@ -60,7 +78,7 @@ private:
QStringList mResult;
PFileIncludes mCurrentIncludes;
int mPreProcIndex;
QStringList mIncludesList;
QHash<QString,PFileIncludes> 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;
@ -70,6 +88,7 @@ private:
QStringList mProjectIncludePaths;
bool mParseSystem;
bool mParseLocal;
QSet<QString> mScannedFiles;
QSet<QString> mProcessed; // dictionary to save filename already processed
};

View File

@ -1,5 +1,8 @@
#include "statementmodel.h"
#include <QFile>
#include <QTextStream>
StatementModel::StatementModel(QObject *parent) : QObject(parent)
{
mCount = 0;
@ -54,6 +57,15 @@ void StatementModel::clear() {
mGlobalStatements.clear();
}
void StatementModel::dump(const QString &logFile)
{
QFile file(logFile);
if (file.open(QFile::WriteOnly | QFile::Truncate)) {
QTextStream out(&file);
dumpStatementMap(mGlobalStatements,out,0);
}
}
void StatementModel::addMember(StatementMap &map, PStatement statement)
{
if (!statement)
@ -76,3 +88,28 @@ int StatementModel::deleteMember(StatementMap &map, PStatement statement)
}
return lst->removeAll(statement);
}
void StatementModel::dumpStatementMap(StatementMap &map, QTextStream &out, int level)
{
QString indent(' ',level);
for (PStatementList lst:map) {
for (PStatement statement:(*lst)) {
out<<indent<<QString("%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12")
.arg(statement->command).arg(int(statement->kind))
.arg(statement->type).arg(statement->fullName)
.arg((size_t)(statement->parentScope.lock().get()))
.arg((int)statement->classScope)
.arg(statement->fileName)
.arg(statement->line)
.arg(statement->endLine)
.arg(statement->definitionFileName)
.arg(statement->definitionLine)
.arg(statement->definitionEndLine)<<Qt::endl;
if (statement->children.isEmpty())
continue;
out<<indent<<statement->command<<" {"<<Qt::endl;
dumpStatementMap(statement->children,out,level+1);
out<<indent<<"}"<<Qt::endl;
}
}
}

View File

@ -2,6 +2,7 @@
#define STATEMENTMODEL_H
#include <QObject>
#include <QTextStream>
#include "utils.h"
class StatementModel : public QObject
@ -17,14 +18,14 @@ public:
const StatementMap& childrenStatements(PStatement statement = PStatement());
const StatementMap& childrenStatements(std::weak_ptr<Statement> statement);
void clear();
void dumpTo(const QString& logFile);
void dumpWithScope(const QString& logFile);
void dump(const QString& logFile);
signals:
private:
void addMember(StatementMap& map, PStatement statement);
int deleteMember(StatementMap& map, PStatement statement);
void dumpStatementMap(StatementMap& map, QTextStream& out, int level);
private:
int mCount;
StatementMap mGlobalStatements; //may have overloaded functions, so use PStatementList to store

View File

@ -208,7 +208,7 @@ void *SynEditStringList::getObject(int Index)
QString SynEditStringList::text()
{
return GetTextStr();
return getTextStr();
}
void SynEditStringList::setText(const QString &text)
@ -348,7 +348,7 @@ void SynEditStringList::deleteAt(int Index)
endUpdate();
}
QString SynEditStringList::GetTextStr()
QString SynEditStringList::getTextStr()
{
QString Result;
for (PSynEditStringRec& line:mList) {

View File

@ -111,7 +111,7 @@ signals:
void inserted(int index, int count);
void putted(int index, int count);
protected:
QString GetTextStr();
QString getTextStr();
void SetUpdateState(bool Updating);
void InsertItem(int Index, const QString& s);
void addItem(const QString& s);