work save
This commit is contained in:
parent
f9c3fb8dd5
commit
91a63648d5
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue