work save

This commit is contained in:
royqh1979@gmail.com 2021-08-09 09:11:10 +08:00
parent 00cc0f0a72
commit 3c3b606cc5
2 changed files with 114 additions and 2 deletions

View File

@ -113,7 +113,7 @@ QString CppPreprocessor::expandMacros(const QString &line, int depth)
int i=0; int i=0;
while (i< lenLine) { while (i< lenLine) {
QChar ch=line[i]; QChar ch=line[i];
if (isIdentChar(ch)) { if (isWordChar(ch)) {
word += ch; word += ch;
} else { } else {
if (!word.isEmpty()) { if (!word.isEmpty()) {
@ -285,7 +285,7 @@ void CppPreprocessor::addDefinesInFile(const QString &fileName)
} }
} }
bool CppPreprocessor::isIdentChar(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')) {
return true; return true;
@ -293,7 +293,109 @@ bool CppPreprocessor::isIdentChar(const QChar &ch)
return false; return false;
} }
bool CppPreprocessor::isIdentChar(const QChar &ch)
{
if (ch=='_' || ch == '*' || ch == '&' || ch == '~' ||
(ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9')) {
return true;
}
return false;
}
QString CppPreprocessor::lineBreak() QString CppPreprocessor::lineBreak()
{ {
return "\n"; return "\n";
} }
bool CppPreprocessor::evaluateIf(const QString &line)
{
QString newLine = expandDefines(line); // replace FOO by numerical value of FOO
newLine = evaluateDefines(newLine); // replace all defined() by 1 or 0
retrun StrToIntDef(removeSuffixes(evaluateExpression(newLine)), -1) > 0;
}
QString CppPreprocessor::expandDefines(const QString &line)
{
int searchPos = 0;
while (searchPos < line.length()) {
// We have found an identifier. It is not a number suffix. Try to expand it
if (Line[SearchPos] in MacroIdentChars) and ((SearchPos = 1) or not (Line[SearchPos - 1] in ['0'..'9'])) then begin
Tail := SearchPos;
Head := SearchPos;
// Get identifier name (numbers are allowed, but not at the start
while (Head <= Length(Line)) and ((Line[Head] in MacroIdentChars) or (Line[Head] in ['0'..'9'])) do
Inc(Head);
Name := Copy(Line, Tail, Head - Tail);
NameStart := Tail;
NameEnd := Head;
// Skip over contents of these built-in functions
if Name = 'defined' then begin
Head := SearchPos + Length(Name);
while (Head <= Length(Line)) and (Line[Head] in SpaceChars) do
Inc(Head); // skip spaces
Head1:=Head;
// Skip over its arguments
if SkipBraces(Line, Head) then begin
SearchPos := Head;
end else begin
//Skip none braced argument (next word)
{
Line := ''; // broken line
break;
}
Head:=Head1;
if (Head>Length(Line)) or not (Line[SearchPos] in MacroIdentChars) then begin
Line := ''; // broken line
break;
end;
while (Head <= Length(Line)) and ((Line[Head] in MacroIdentChars) or (Line[Head] in ['0'..'9'])) do
Inc(Head);
end;
SearchPos := Head;
end else if (Name = 'and') or (Name = 'or') then begin
SearchPos := Head; // Skip logical operators
// We have found a regular define. Replace it by its value
end else begin
// Does it exist in the database?
Define := GetDefine(Name,Dummy);
if not Assigned(Define) then begin
InsertValue := '0';
end else begin
while (Head <= Length(Line)) and (Line[Head] in SpaceChars) do
Inc(Head); // skip spaces
// It is a function. Expand arguments
if (Head <= Length(Line)) and (Line[Head] = '(') then begin
Tail := Head;
if SkipBraces(Line, Head) then begin
Args := Copy(Line, Tail, Head - Tail + 1);
InsertValue := ExpandFunction(Define, Args);
NameEnd := Head + 1;
end else begin
Line := ''; // broken line
break;
end;
// Replace regular define
end else begin
if Define^.Value <> '' then
InsertValue := Define^.Value
else
InsertValue := '0';
end;
end;
// Insert found value at place
Delete(Line, NameStart, NameEnd - NameStart);
Insert(InsertValue, Line, SearchPos);
end;
end else
Inc(SearchPos);
end;
Result := Line;
}

View File

@ -68,9 +68,19 @@ private:
PFileIncludes getFileIncludesEntry(const QString& FileName); PFileIncludes getFileIncludesEntry(const QString& FileName);
void addDefinesInFile(const QString& fileName); void addDefinesInFile(const QString& fileName);
/*
* '_','a'..'z','A'..'Z','0'..'9'
*/
bool isWordChar(const QChar& ch);
/*
* 'A'..'Z', '0'..'9', 'a'..'z', '_', '*', '&', '~'
*/
bool isIdentChar(const QChar& ch); bool isIdentChar(const QChar& ch);
QString lineBreak(); QString lineBreak();
bool evaluateIf(const QString& line);
QString expandDefines(const QString& line);
private: private:
int mIndex; // points to current file buffer. do not free int mIndex; // points to current file buffer. do not free
QString mFileName; // idem QString mFileName; // idem