- enhancement: Better support for expanding macros with complex parameters.

This commit is contained in:
Roy Qu 2023-10-25 00:19:05 +08:00
parent 5ac89f1bab
commit 0bc361e1f9
4 changed files with 62 additions and 36 deletions

View File

@ -14,7 +14,8 @@ Red Panda C++ Version 2.26
- fix: Should cd to working directory when debugging. - fix: Should cd to working directory when debugging.
- change: Ensure the line just below caret is visible while moving caret. - change: Ensure the line just below caret is visible while moving caret.
- change: Set mouse cursor to hand pointing when it's on gutter. - change: Set mouse cursor to hand pointing when it's on gutter.
- enhancement: Basic support for parsing variadic macros. - enhancement: Basic support for parsing variadic macros(macros that use __VA_ARGS__).
- enhancement: Better support for expanding macros with complex parameters.
Red Panda C++ Version 2.25 Red Panda C++ Version 2.25

View File

@ -1114,7 +1114,7 @@ void DebugReader::processLogOutput(const QByteArray &line)
int p=newLine.lastIndexOf(':'); int p=newLine.lastIndexOf(':');
if (p>0) { if (p>0) {
newLine=newLine.left(p); newLine=newLine.left(p);
qDebug()<<newLine; //qDebug()<<newLine;
processConsoleOutput(newLine); processConsoleOutput(newLine);
} }
} }

View File

@ -4397,8 +4397,8 @@ void CppParser::internalParse(const QString &fileName)
QStringList preprocessResult = mPreprocessor.result(); QStringList preprocessResult = mPreprocessor.result();
#ifdef QT_DEBUG #ifdef QT_DEBUG
// stringsToFile(mPreprocessor.result(),QString("r:\\preprocess-%1.txt").arg(extractFileName(fileName))); stringsToFile(mPreprocessor.result(),QString("r:\\preprocess-%1.txt").arg(extractFileName(fileName)));
// mPreprocessor.dumpDefinesTo("r:\\defines.txt"); mPreprocessor.dumpDefinesTo("r:\\defines.txt");
// mPreprocessor.dumpIncludesListTo("r:\\includes.txt"); // mPreprocessor.dumpIncludesListTo("r:\\includes.txt");
#endif #endif
//qDebug()<<"preprocess"<<timer.elapsed(); //qDebug()<<"preprocess"<<timer.elapsed();
@ -4416,7 +4416,7 @@ void CppParser::internalParse(const QString &fileName)
if (mTokenizer.tokenCount() == 0) if (mTokenizer.tokenCount() == 0)
return; return;
#ifdef QT_DEBUG #ifdef QT_DEBUG
// mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName))); mTokenizer.dumpTokens(QString("r:\\tokens-%1.txt").arg(extractFileName(fileName)));
#endif #endif
#ifdef QT_DEBUG #ifdef QT_DEBUG
mLastIndex = -1; mLastIndex = -1;
@ -4429,8 +4429,8 @@ void CppParser::internalParse(const QString &fileName)
} }
// qDebug()<<"parse"<<timer.elapsed(); // qDebug()<<"parse"<<timer.elapsed();
#ifdef QT_DEBUG #ifdef QT_DEBUG
// mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName))); mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName)));
// mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName))); mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName)));
#endif #endif
//reduce memory usage //reduce memory usage
internalClear(); internalClear();

View File

@ -73,6 +73,7 @@ void CppPreprocessor::addDefineByParts(const QString &name, const QString &args,
//define->argList; //define->argList;
define->formatValue = value; define->formatValue = value;
define->hardCoded = hardCoded; define->hardCoded = hardCoded;
define->varArgIndex = -1;
if (!args.isEmpty()) if (!args.isEmpty())
parseArgs(define); parseArgs(define);
if (hardCoded) { if (hardCoded) {
@ -946,7 +947,6 @@ void CppPreprocessor::parseArgs(PDefine define)
define->argList[i]=define->argList[i].trimmed(); define->argList[i]=define->argList[i].trimmed();
define->argUsed.append(false); define->argUsed.append(false);
} }
define->varArgIndex=-1;
QList<PDefineArgToken> tokens = tokenizeValue(define->value); QList<PDefineArgToken> tokens = tokenizeValue(define->value);
QString formatStr = ""; QString formatStr = "";
@ -1448,25 +1448,48 @@ QString CppPreprocessor::expandFunction(PDefine define, QString args)
{ {
// Replace function by this string // Replace function by this string
QString result = define->formatValue; QString result = define->formatValue;
if (args.startsWith('(') && args.endsWith(')')) { // if (args.startsWith('(') && args.endsWith(')')) {
args = args.mid(1,args.length()-2); // qDebug()<<define->name<<args;
} // args = args.mid(1,args.length()-2);
// }
if (define->argList.length()==0) {
// do nothing
} else if (define->argList.length()==1) {
result=result.arg(args);
} else {
QStringList argValues; QStringList argValues;
int i=0; int i=0;
bool inString = false; bool inString = false;
bool inChar = false;
int lastSplit=0; int lastSplit=0;
int level=0;
while (i<args.length()) { while (i<args.length()) {
switch(args[i].unicode()) { switch(args[i].unicode()) {
case '\\': case '\\':
if (inString) if (inString || inChar)
i++; i++;
break; break;
case '(':
case '{':
if (!inString && !inChar)
level++;
break;
case ')':
case '}':
if (!inString && !inChar)
level--;
break;
case '"': case '"':
if (!inChar)
inString = !inString; inString = !inString;
break; break;
case '\'':
if (!inString)
inChar = !inChar;
break;
case ',': case ',':
if (!inString) { if (!inString && !inChar && level == 0) {
argValues.append(args.mid(lastSplit,i-lastSplit)); argValues.append(args.mid(lastSplit,i-lastSplit));
lastSplit=i+1; lastSplit=i+1;
} }
@ -1488,9 +1511,11 @@ QString CppPreprocessor::expandFunction(PDefine define, QString args)
result=result.arg(argValue.trimmed()); result=result.arg(argValue.trimmed());
} }
} }
if (!varArgs.isEmpty()) if (!varArgs.isEmpty() && define->varArgIndex != -1) {
result=result.arg(varArgs.join(",")); result=result.arg(varArgs.join(","));
} }
}
}
result.replace("%%","%"); result.replace("%%","%");
return result; return result;