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