- 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.
- change: Ensure the line just below caret is visible while moving caret.
- 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

View File

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

View File

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

View File

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