- 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,48 +1448,73 @@ 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);
// }
QStringList argValues; if (define->argList.length()==0) {
int i=0; // do nothing
bool inString = false; } else if (define->argList.length()==1) {
int lastSplit=0; result=result.arg(args);
while (i<args.length()) { } else {
switch(args[i].unicode()) { QStringList argValues;
int i=0;
bool inString = false;
bool inChar = false;
int lastSplit=0;
int level=0;
while (i<args.length()) {
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 '"':
inString = !inString; if (!inChar)
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;
} }
break; break;
}
i++;
} }
i++; argValues.append(args.mid(lastSplit,i-lastSplit));
} if (argValues.length() >= define->argList.length()
argValues.append(args.mid(lastSplit,i-lastSplit)); && argValues.length()>0) {
if (argValues.length() >= define->argList.length() QStringList varArgs;
&& argValues.length()>0) { for (int i=0;i<argValues.length();i++) {
QStringList varArgs; if (define->varArgIndex != -1
for (int i=0;i<argValues.length();i++) { && i >= define->varArgIndex ) {
if (define->varArgIndex != -1 varArgs.append(argValues[i].trimmed());
&& i >= define->varArgIndex ) { } else if (i<define->argList.length()
varArgs.append(argValues[i].trimmed()); && define->argUsed[i]) {
} else if (i<define->argList.length() QString argValue = argValues[i];
&& define->argUsed[i]) { result=result.arg(argValue.trimmed());
QString argValue = argValues[i]; }
result=result.arg(argValue.trimmed()); }
if (!varArgs.isEmpty() && define->varArgIndex != -1) {
result=result.arg(varArgs.join(","));
} }
} }
if (!varArgs.isEmpty())
result=result.arg(varArgs.join(","));
} }
result.replace("%%","%"); result.replace("%%","%");