From 0040d5a582b7fb7e9719d7c04c8de272e2a1389d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 23 Sep 2009 14:59:04 +0200 Subject: reduce peak memory consumption drop the parse results of files which are unlikely to be included (i.e., which are not headers). --- tools/linguist/lupdate/cpp.cpp | 100 ++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 30 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 44a8feb..0a710e2 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -120,6 +120,10 @@ struct Namespace { classDef(this), hasTrFunctions(false), complained(false) {} + ~Namespace() + { + qDeleteAll(children); + } QHash children; QHash aliases; @@ -159,30 +163,27 @@ private: }; struct ParseResults { - - ParseResults() - { - tor = 0; - } - int fileId; Namespace rootNamespace; - Translator *tor; QSet includes; }; typedef QHash ParseResultHash; +typedef QHash TranslatorHash; class CppFiles { public: static const ParseResults *getResults(const QString &cleanFile); static void setResults(const QString &cleanFile, ParseResults *results); + static const Translator *getTranslator(const QString &cleanFile); + static void setTranslator(const QString &cleanFile, const Translator *results); static bool isBlacklisted(const QString &cleanFile); static void setBlacklisted(const QString &cleanFile); private: static ParseResultHash &parsedFiles(); + static TranslatorHash &translatedFiles(); static QSet &blacklistedFiles(); }; @@ -192,10 +193,10 @@ public: CppParser(ParseResults *results = 0); void setInput(const QString &in); void setInput(QTextStream &ts, const QString &fileName); - void setTranslator(Translator *tor) { results->tor = tor; } + void setTranslator(Translator *_tor) { tor = _tor; } void parse(const QString &initialContext, ConversionData &cd, QSet &inclusions); void parseInternal(ConversionData &cd, QSet &inclusions); - ParseResults *getResults() const { return results; } + const ParseResults *recordResults(bool isHeader); void deleteResults() { delete results; } struct SavedState { @@ -311,6 +312,7 @@ private: QString prospectiveContext; QString pendingContext; ParseResults *results; + Translator *tor; bool directInclude; SavedState savedState; @@ -320,6 +322,7 @@ private: CppParser::CppParser(ParseResults *_results) { + tor = 0; if (_results) { results = _results; directInclude = true; @@ -1166,6 +1169,13 @@ ParseResultHash &CppFiles::parsedFiles() return parsed; } +TranslatorHash &CppFiles::translatedFiles() +{ + static TranslatorHash tors; + + return tors; +} + QSet &CppFiles::blacklistedFiles() { static QSet blacklisted; @@ -1184,6 +1194,16 @@ void CppFiles::setResults(const QString &cleanFile, ParseResults *results) parsedFiles().insert(cleanFile, results); } +const Translator *CppFiles::getTranslator(const QString &cleanFile) +{ + return translatedFiles().value(cleanFile); +} + +void CppFiles::setTranslator(const QString &cleanFile, const Translator *tor) +{ + translatedFiles().insert(cleanFile, tor); +} + bool CppFiles::isBlacklisted(const QString &cleanFile) { return blacklistedFiles().contains(cleanFile); @@ -1194,6 +1214,12 @@ void CppFiles::setBlacklisted(const QString &cleanFile) blacklistedFiles().insert(cleanFile); } +static bool isHeader(const QString &name) +{ + QString fileExt = QFileInfo(name).suffix(); + return fileExt.isEmpty() || fileExt.startsWith(QLatin1Char('h'), Qt::CaseInsensitive); +} + void CppParser::processInclude(const QString &file, ConversionData &cd, QSet &inclusions) { @@ -1212,17 +1238,15 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, bool isIndirect = false; if (namespaces.count() == 1 && functionContext.count() == 1 && functionContextUnresolved.isEmpty() && pendingContext.isEmpty() - && !CppFiles::isBlacklisted(cleanFile)) { - QString fileExt = QFileInfo(cleanFile).suffix(); - if (fileExt.isEmpty() || fileExt.startsWith(QLatin1Char('h'), Qt::CaseInsensitive)) { - - if (const ParseResults *res = CppFiles::getResults(cleanFile)) { - results->includes.insert(res); - return; - } + && !CppFiles::isBlacklisted(cleanFile) + && isHeader(cleanFile)) { - isIndirect = true; + if (const ParseResults *res = CppFiles::getResults(cleanFile)) { + results->includes.insert(res); + return; } + + isIndirect = true; } QFile f(cleanFile); @@ -1247,8 +1271,7 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, } parser.setInput(ts, cleanFile); parser.parse(cd.m_defaultContext, cd, inclusions); - CppFiles::setResults(cleanFile, parser.results); - results->includes.insert(parser.results); + results->includes.insert(parser.recordResults(true)); } else { CppParser parser(results); parser.namespaces = namespaces; @@ -1434,14 +1457,14 @@ void CppParser::recordMessage( msg.setExtras(extra); if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit()) msg.setUtf8(true); - results->tor->append(msg); + tor->append(msg); } void CppParser::parse(const QString &initialContext, ConversionData &cd, QSet &inclusions) { - if (results->tor) - yyCodecIsUtf8 = (results->tor->codecName() == "UTF-8"); + if (tor) + yyCodecIsUtf8 = (tor->codecName() == "UTF-8"); namespaces << HashString(); functionContext = namespaces; @@ -1657,7 +1680,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; case Tok_tr: case Tok_trUtf8: - if (!results->tor) + if (!tor) goto case_default; if (!sourcetext.isEmpty()) qWarning("%s:%d: //%% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n", @@ -1770,7 +1793,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; case Tok_translateUtf8: case Tok_translate: - if (!results->tor) + if (!tor) goto case_default; if (!sourcetext.isEmpty()) qWarning("%s:%d: //%% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n", @@ -1825,7 +1848,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) extra.clear(); break; case Tok_trid: - if (!results->tor) + if (!tor) goto case_default; if (sourcetext.isEmpty()) { yyTok = getToken(); @@ -1871,7 +1894,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } break; case Tok_Comment: - if (!results->tor) + if (!tor) goto case_default; if (yyWord.startsWith(QLatin1Char(':'))) { yyWord.remove(0, 1); @@ -1944,7 +1967,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) recordMessage(yyLineNo, context, QString(), comment, extracomment, QString(), TranslatorMessage::ExtraData(), false, false); extracomment.clear(); - results->tor->setExtras(extra); + tor->setExtras(extra); extra.clear(); } } @@ -2029,6 +2052,23 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) qPrintable(yyFileName), yyParenLineNo); } +const ParseResults *CppParser::recordResults(bool isHeader) +{ + if (tor) { + if (tor->messageCount()) + CppFiles::setTranslator(yyFileName, tor); + else + delete tor; + } + if (isHeader) { + CppFiles::setResults(yyFileName, results); + return results; + } else { + delete results; + return 0; + } +} + /* Fetches tr() calls in C++ code in UI files (inside "" tag). This mechanism is obsolete. @@ -2073,12 +2113,12 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat parser.setTranslator(tor); QSet inclusions; parser.parse(cd.m_defaultContext, cd, inclusions); - CppFiles::setResults(filename, parser.getResults()); + parser.recordResults(isHeader(filename)); } foreach (const QString &filename, filenames) if (!CppFiles::isBlacklisted(filename)) - if (Translator *tor = CppFiles::getResults(filename)->tor) + if (const Translator *tor = CppFiles::getTranslator(filename)) foreach (const TranslatorMessage &msg, tor->messages()) translator.extend(msg); } -- cgit v0.12