work save

This commit is contained in:
royqh1979@gmail.com 2021-08-12 21:25:13 +08:00
parent 9c42a11c0b
commit 7d30690227
3 changed files with 227 additions and 13 deletions

View File

@ -7,6 +7,64 @@ CppPreprocessor::CppPreprocessor(QObject *parent) : QObject(parent)
{ {
} }
void CppPreprocessor::clear()
{
mIncludes.clear();
mDefines.clear();
mHardDefines.clear();
mProcessed.clear();
mFileDefines.clear();
mBranchResults.clear();
mResult.clear();
mCurrentIncludes.reset();
mScannedFiles.reset();
}
void CppPreprocessor::addDefineByParts(const QString &name, const QString &args, const QString &value, bool hardCoded)
{
// Check for duplicates
PDefine define = std::make_shared<Define>();
define->name = name;
define->args = args;
define->value = value;
define->filename = mFileName;
//define->argList;
define->formatValue = value;
define->hardCoded = hardCoded;
if (!args.isEmpty())
parseArgs(define);
if (hardCoded)
mHardDefines.insert(name,define);
else {
PDefineMap defineMap = mFileDefines.value(mFileName,PDefineMap());
if (!defineMap) {
defineMap = std::make_shared<DefineMap>();
mFileDefines.insert(mFileName,defineMap);
}
defineMap->insert(define->name,define);
mDefines.insert(name,define);
}
}
void CppPreprocessor::getDefineParts(const QString &Input, QString &name, QString &args, QString &value)
{
}
void CppPreprocessor::addDefineByLine(const QString &line, bool hardCoded)
{
// Remove define
constexpr int DEFINE_LEN=6;
QString s = line.mid(DEFINE_LEN,0).trimmed();
QString name, args, value;
// Get parts from generalized function
getDefineParts(s, name, args, value);
// Add to the list
addDefineByParts(name, args, value, hardCoded);
}
QString CppPreprocessor::getNextPreprocessor() QString CppPreprocessor::getNextPreprocessor()
{ {
@ -20,10 +78,14 @@ QString CppPreprocessor::getNextPreprocessor()
// Calculate index to insert defines in in result file // Calculate index to insert defines in in result file
mPreProcIndex = (mResult.count() - 1) + 1; // offset by one for #include rootfile mPreProcIndex = (mResult.count() - 1) + 1; // offset by one for #include rootfile
// Assemble whole line, including newlines // Assemble whole line, convert newlines to space
QString result; QString result;
for (int i=preProcFrom;i<=preProcTo;i++) { for (int i=preProcFrom;i<=preProcTo;i++) {
result+=mBuffer[i]+'\n'; if (mBuffer[i].endsWith('/')) {
result+=mBuffer[i].mid(0,mBuffer[i].size()-1)+' ';
} else {
result+=mBuffer[i]+' ';
}
mResult.append("");// defines resolve into empty files, except #define and #include mResult.append("");// defines resolve into empty files, except #define and #include
} }
// Step over // Step over
@ -31,6 +93,12 @@ QString CppPreprocessor::getNextPreprocessor()
return result; return result;
} }
void CppPreprocessor::simplify(QString &output)
{
// Remove #
output = output.mid(1).trimmed();
}
void CppPreprocessor::handleBranch(const QString &line) void CppPreprocessor::handleBranch(const QString &line)
{ {
if (line.startsWith("ifdef")) { if (line.startsWith("ifdef")) {
@ -222,14 +290,14 @@ void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString
} else { } else {
int index; int index;
PDefine define = getDefine(word,index); PDefine define = getDefine(word,index);
if (define && define->args=="" && (!define->isMultiLine)) { if (define && define->args=="" ) {
//newLine:=newLine+RemoveGCCAttributes(define^.Value); //newLine:=newLine+RemoveGCCAttributes(define^.Value);
if (define->value != word ) if (define->value != word )
newLine += expandMacros(define->value,depth+1); newLine += expandMacros(define->value,depth+1);
else else
newLine += word; newLine += word;
} else if (define && (!define->isMultiLine) && (define->args!="")) { } else if (define && (define->args!="")) {
while ((i<lenLine) && (line[i] == ' ' || line[i]=='\t')) while ((i<lenLine) && (line[i] == ' ' || line[i]=='\t'))
i++; i++;
int argStart=-1; int argStart=-1;
@ -263,6 +331,57 @@ void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString
} }
} }
QString CppPreprocessor::removeGCCAttributes(const QString &line)
{
QString newLine = "";
QString word = "";
int lenLine = line.length();
int i=1;
while(i< lenLine) {
if (isWordChar(line[i])) {
word += line[i];
} else {
if (!word.isEmpty()) {
removeGCCAttribute(line,newLine,i,word);
}
word = "";
if (i<=lenLine) {
newLine = newLine+line[i];
}
}
i++;
}
if (!word.isEmpty())
removeGCCAttribute(line,newLine,i,word);
return newLine;
}
void CppPreprocessor::removeGCCAttribute(const QString &line, QString &newLine, int &i, const QString &word)
{
int lenLine = line.length();
int level = 0;
if (word=="__attribute__") {
while ( (i<lenLine) && isSpaceChar(line[i]))
i++;
if ((i<lenLine) && (line[i]=='(')) {
level=0;
while (i<lenLine) {
switch(line[i].unicode()) {
case '(': level++;
break;
case ')': level--;
break;
}
i++;
if (level==0)
break;
}
}
} else {
newLine += word;
}
}
PParsedFile CppPreprocessor::getInclude(int index) PParsedFile CppPreprocessor::getInclude(int index)
{ {
return mIncludes[index]; return mIncludes[index];
@ -328,10 +447,10 @@ void CppPreprocessor::openInclude(const QString &fileName, QStringList bufferedT
parsedFile->fileIncludes = mCurrentIncludes; parsedFile->fileIncludes = mCurrentIncludes;
// Don't parse stuff we have already parsed // Don't parse stuff we have already parsed
if ((!bufferedText.isEmpty()) || !mScannedFiles.contains(fileName)) { if ((!bufferedText.isEmpty()) || !mScannedFiles->contains(fileName)) {
// Parse ONCE // Parse ONCE
//if not Assigned(Stream) then //if not Assigned(Stream) then
mScannedFiles.insert(fileName); mScannedFiles->insert(fileName);
// Only load up the file if we are allowed to parse it // Only load up the file if we are allowed to parse it
bool isSystemFile = isSystemHeaderFile(fileName, mIncludePaths); bool isSystemFile = isSystemHeaderFile(fileName, mIncludePaths);
@ -433,7 +552,7 @@ void CppPreprocessor::addDefinesInFile(const QString &fileName)
mProcessed.insert(fileName); mProcessed.insert(fileName);
//todo: why test this? //todo: why test this?
if (!mScannedFiles.contains(fileName)) if (!mScannedFiles->contains(fileName))
return; return;
//May be redefined, so order is important //May be redefined, so order is important
@ -454,6 +573,78 @@ void CppPreprocessor::addDefinesInFile(const QString &fileName)
} }
} }
void CppPreprocessor::parseArgs(PDefine define)
{
QString args=define->args.mid(1,define->args.length()-2).trimmed(); // remove '(' ')'
if(args=="")
return ;
define->argList = args.split(',');
for (int i;i<define->argList.size();i++) {
define->argList[i]=define->argList[i].trimmed();
}
QStringList tokens = tokenizeValue(define->value);
QString formatStr = "";
QString lastToken = "##";
for (QString token: tokens) {
if (lastToken != "##" && token!="##") {
formatStr += ' ';
}
int index = define->argList.indexOf(token);
if (index>=0) {
if (lastToken == "#") {
formatStr+= "\"%"+QString("%1").arg(index+1)+"\"";
} else {
formatStr+= "%"+QString("%1").arg(index+1);
}
} else if (token == "%"){
formatStr+="%%";
}
lastToken = token;
}
define->formatValue = formatStr;
}
QStringList CppPreprocessor::tokenizeValue(const QString &value)
{
int i=0;
QString token;
QStringList tokens;
while (i<value.length()) {
QChar ch = value[i];
if (isSpaceChar(ch)) {
if(!token.isEmpty())
tokens.append(token);
token = "";
i++;
} else if (ch=='#') {
if(!token.isEmpty())
tokens.append(token);
token = "";
if ((i+1<value.length()) && (value[i+1]=='#')) {
i+=2;
tokens.append("##");
} else {
i++;
tokens.append("#");
}
} else if (isWordChar(ch)) {
token+=ch;
i++;
} else {
if(!token.isEmpty())
tokens.append(token);
token = "";
tokens.append(ch);
i++;
}
}
if(!token.isEmpty())
tokens.append(token);
return tokens;
}
QStringList CppPreprocessor::removeComments(const QStringList &text) QStringList CppPreprocessor::removeComments(const QStringList &text)
{ {
QStringList result; QStringList result;
@ -461,7 +652,6 @@ QStringList CppPreprocessor::removeComments(const QStringList &text)
QString delimiter; QString delimiter;
for (QString line:text) { for (QString line:text) {
QChar lastCh;
QString s; QString s;
int pos = 0; int pos = 0;
bool stopProcess=false; bool stopProcess=false;
@ -578,6 +768,25 @@ void CppPreprocessor::preprocessBuffer()
} }
} }
void CppPreprocessor::skipToEndOfPreprocessor()
{
// Skip until last char of line is NOT \ anymore
while ((mIndex < mBuffer.count()) && mBuffer[mIndex].endsWith('\\'))
mIndex++;
}
void CppPreprocessor::skipToPreprocessor()
{
// Increment until a line begins with a #
while ((mIndex < mBuffer.count()) && !mBuffer[mIndex].startsWith('#')) {
if (getCurrentBranch()) // if not skipping, expand current macros
mResult.append(expandMacros(mBuffer[mIndex],1));
else // If skipping due to a failed branch, clear line
mResult.append("");
mIndex++;
}
}
bool CppPreprocessor::isWordChar(const QChar &ch) bool CppPreprocessor::isWordChar(const QChar &ch)
{ {
if (ch=='_' || (ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9')) { if (ch=='_' || (ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9')) {
@ -795,8 +1004,10 @@ QString CppPreprocessor::expandFunction(PDefine define, QString args)
QStringList argValues = args.split(","); QStringList argValues = args.split(",");
for (QString argValue:argValues) { for (QString argValue:argValues) {
result=result.arg(argValue); result=result.arg(argValue.trimmed());
} }
result.replace("%%","%");
return result; return result;
} }

View File

@ -67,7 +67,8 @@ private:
QString expandMacros(const QString& line, int depth); QString expandMacros(const QString& line, int depth);
void expandMacro(const QString& line, QString& newLine, QString& word, int& i, int depth); void expandMacro(const QString& line, QString& newLine, QString& word, int& i, int depth);
QString removeGCCAttributes(const QString& line); QString removeGCCAttributes(const QString& line);
QString removeSuffixes(const QString& input); void removeGCCAttribute(const QString&line, QString& newLine, int &i, const QString& word);
// current file stuff // current file stuff
PParsedFile getInclude(int index); PParsedFile getInclude(int index);
void openInclude(const QString& fileName, QStringList bufferedText=QStringList()); void openInclude(const QString& fileName, QStringList bufferedText=QStringList());
@ -77,11 +78,14 @@ private:
bool getCurrentBranch(); bool getCurrentBranch();
void setCurrentBranch(bool value); void setCurrentBranch(bool value);
void removeCurrentBranch(); void removeCurrentBranch();
QString getResult(); QStringList getResult();
// include stuff // include stuff
PFileIncludes getFileIncludesEntry(const QString& FileName); PFileIncludes getFileIncludesEntry(const QString& FileName);
void addDefinesInFile(const QString& fileName); void addDefinesInFile(const QString& fileName);
void parseArgs(PDefine define);
QStringList tokenizeValue(const QString& value);
QStringList removeComments(const QStringList& text); QStringList removeComments(const QStringList& text);
/* /*
* '_','a'..'z','A'..'Z','0'..'9' * '_','a'..'z','A'..'Z','0'..'9'
@ -159,7 +163,7 @@ private:
QStringList mProjectIncludePaths; QStringList mProjectIncludePaths;
bool mParseSystem; bool mParseSystem;
bool mParseLocal; bool mParseLocal;
QSet<QString> mScannedFiles; std::shared_ptr<QSet<QString>> mScannedFiles;
QSet<QString> mProcessed; // dictionary to save filename already processed QSet<QString> mProcessed; // dictionary to save filename already processed
}; };

View File

@ -10,7 +10,6 @@ struct Define {
QString args; QString args;
QString value; QString value;
QString filename; QString filename;
bool isMultiLine; // if true the expanded macro will span multiline
bool hardCoded;// if true, don't free memory (points to hard defines) bool hardCoded;// if true, don't free memory (points to hard defines)
QStringList argList; // args list to format values QStringList argList; // args list to format values
QString formatValue; // format template to format values QString formatValue; // format template to format values