work save

This commit is contained in:
royqh1979@gmail.com 2021-08-07 23:30:01 +08:00
parent f0a0ae44b7
commit f9c3fb8dd5
2 changed files with 143 additions and 2 deletions

View File

@ -5,6 +5,136 @@ CppPreprocessor::CppPreprocessor(QObject *parent) : QObject(parent)
}
QString CppPreprocessor::expandMacros(const QString &line, int depth)
{
//prevent infinit recursion
if (depth > 20)
return line;
QString word;
QString newLine;
int lenLine = line.length();
int i=0;
while (i< lenLine) {
QChar ch=line[i];
if (isIdentChar(ch)) {
word += ch;
} else {
if (!word.isEmpty()) {
expandMacro(line,newLine,word,i,depth);
}
word = "";
if (i< lenLine) {
newLine += ch;
}
}
i++;
}
if (!word.isEmpty()) {
expandMacro(line,newLine,word,i,depth);
}
return newLine;
}
void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString &word, int &i, int depth)
{
int lenLine = line.length();
if (word == "__attribute__") {
//skip gcc __attribute__
while ((i<lenLine) && (line[i] == ' ' || line[i]=='\t'))
i++;
if ((i<lenLine) && (line[i]=="(")) {
int level=0;
while (i<lenLine) {
switch(line[i].unicode()) {
case '(':
level++;
break;
case ')':
level--;
break;
}
i++;
if (level==0)
break;
}
}
} else {
int index;
PDefine define = getDefine(word,index);
if (define && define->args=="" && (!define->isMultiLine)) {
//newLine:=newLine+RemoveGCCAttributes(define^.Value);
if (define->value != word )
newLine += expandMacros(define->value,depth+1);
else
newLine += word;
} else if (define && (!define->isMultiLine) && (define->args!="")) {
while ((i<lenLine) && (line[i] == ' ' || line[i]=='\t'))
i++;
int argStart=-1;
int argEnd=-1;
if ((i<lenLine) && (line[i]=='(')) {
argStart =i+1;
int level=0;
while (i<lenLine) {
switch(line[i].unicode()) {
case '(':
level++;
break;
case ')':
level--;
break;
}
i++;
if (level==0)
break;
}
if (level==0) {
argEnd = i-2;
QString arg = line.mid(argStart,argEnd-argStart+1).trimmed();
QString formattedValue = define->formatValue;
for (int i=0;i<define->argList.count();i++) {
formattedValue = formattedValue.arg(arg);
}
newLine += expandMacros(formattedValue,depth+1);
}
}
} else {
newLine += word;
}
}
}
void CppPreprocessor::closeInclude()
{
if (mIncludes.isEmpty())
return;
mIncludes.pop_back();
if (mIncludes.isEmpty())
return;
PParsedFile parsedFile = mIncludes.back();
// Continue where we left off
mIndex = parsedFile->index;
mFileName = parsedFile->fileName;
// Point to previous buffer and start past the include we walked into
mBuffer = parsedFile->buffer;
while (mBranchResults.count()>parsedFile->branches) {
mBranchResults.pop_back();
}
// Start augmenting previous include list again
//fCurrentIncludes := GetFileIncludesEntry(fFileName);
mCurrentIncludes = parsedFile->fileIncludes;
// Update result file (we've left the previous file)
mResult.append(
QString("#include %1:%2").arg(parsedFile->fileName)
.arg(parsedFile->index+1));
}
void CppPreprocessor::addDefinesInFile(const QString &fileName)
{
if (mProcessed.contains(fileName))
@ -26,3 +156,11 @@ void CppPreprocessor::addDefinesInFile(const QString &fileName)
}
}
}
bool CppPreprocessor::isIdentChar(const QChar &ch)
{
if (ch=='_' || (ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9')) {
return true;
}
return false;
}

View File

@ -35,13 +35,14 @@ private:
void handleBranch(const QString& line);
void handleInclude(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);
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);
@ -50,6 +51,8 @@ private:
// include stuff
PFileIncludes getFileIncludesEntry(const QString& FileName);
void addDefinesInFile(const QString& fileName);
bool isIdentChar(const QChar& ch);
private:
int mIndex; // points to current file buffer. do not free
QString mFileName; // idem
@ -62,7 +65,7 @@ private:
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
QList<bool> mBranchResults;// 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;