summaryrefslogtreecommitdiffstats
path: root/tools/linguist/lupdate/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/linguist/lupdate/main.cpp')
-rw-r--r--tools/linguist/lupdate/main.cpp256
1 files changed, 150 insertions, 106 deletions
diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp
index 274e33c..76a8756 100644
--- a/tools/linguist/lupdate/main.cpp
+++ b/tools/linguist/lupdate/main.cpp
@@ -52,21 +52,22 @@
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QTextCodec>
+#include <QtCore/QTranslator>
+#include <QtCore/QLibraryInfo>
#include <iostream>
static QString m_defaultExtensions;
-static void printErr(const QString & out)
-{
- qWarning("%s", qPrintable(out));
-}
-
static void printOut(const QString & out)
{
std::cerr << qPrintable(out);
}
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
static void recursiveFileInfoList(const QDir &dir,
const QSet<QString> &nameFilters, QDir::Filters filter,
QFileInfoList *fileinfolist)
@@ -80,10 +81,10 @@ static void recursiveFileInfoList(const QDir &dir,
static void printUsage()
{
- printOut(QObject::tr(
+ printOut(LU::tr(
"Usage:\n"
" lupdate [options] [project-file]...\n"
- " lupdate [options] [source-file|path]... -ts ts-files\n\n"
+ " lupdate [options] [source-file|path|@lst-file]... -ts ts-files|@lst-file\n\n"
"lupdate is part of Qt's Linguist tool chain. It extracts translatable\n"
"messages from Qt UI files, C++, Java and JavaScript/QtScript source code.\n"
"Extracted messages are stored in textual translation source files (typically\n"
@@ -132,6 +133,8 @@ static void printUsage()
" Specify the codec assumed for tr() calls. Effective only with -ts.\n"
" -version\n"
" Display the version of lupdate and exit.\n"
+ " @lst-file\n"
+ " Read additional file names (one per line) from lst-file.\n"
).arg(m_defaultExtensions));
}
@@ -148,24 +151,25 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
cd.m_sortContexts = !(options & NoSort);
if (QFile(fileName).exists()) {
if (!tor.load(fileName, cd, QLatin1String("auto"))) {
- printErr(cd.error());
+ printOut(cd.error());
*fail = true;
continue;
}
tor.resolveDuplicates();
cd.clearErrors();
if (setCodec && fetchedTor.codec() != tor.codec())
- qWarning("lupdate warning: Codec for tr() '%s' disagrees with "
- "existing file's codec '%s'. Expect trouble.",
- fetchedTor.codecName().constData(), tor.codecName().constData());
+ printOut(LU::tr("lupdate warning: Codec for tr() '%1' disagrees with"
+ " existing file's codec '%2'. Expect trouble.\n")
+ .arg(QString::fromLatin1(fetchedTor.codecName()),
+ QString::fromLatin1(tor.codecName())));
if (!targetLanguage.isEmpty() && targetLanguage != tor.languageCode())
- qWarning("lupdate warning: Specified target language '%s' disagrees with "
- "existing file's language '%s'. Ignoring.",
- qPrintable(targetLanguage), qPrintable(tor.languageCode()));
+ printOut(LU::tr("lupdate warning: Specified target language '%1' disagrees with"
+ " existing file's language '%2'. Ignoring.\n")
+ .arg(targetLanguage, tor.languageCode()));
if (!sourceLanguage.isEmpty() && sourceLanguage != tor.sourceLanguageCode())
- qWarning("lupdate warning: Specified source language '%s' disagrees with "
- "existing file's language '%s'. Ignoring.",
- qPrintable(sourceLanguage), qPrintable(tor.sourceLanguageCode()));
+ printOut(LU::tr("lupdate warning: Specified source language '%1' disagrees with"
+ " existing file's language '%2'. Ignoring.\n")
+ .arg(sourceLanguage, tor.sourceLanguageCode()));
} else {
if (setCodec)
tor.setCodec(fetchedTor.codec());
@@ -184,7 +188,7 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
else if (options & AbsoluteLocations)
tor.setLocationsType(Translator::AbsoluteLocations);
if (options & Verbose)
- printOut(QObject::tr("Updating '%1'...\n").arg(fn));
+ printOut(LU::tr("Updating '%1'...\n").arg(fn));
UpdateOptions theseOptions = options;
if (tor.locationsType() == Translator::NoLocations) // Could be set from file
@@ -199,7 +203,7 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
}
if (options & PluralOnly) {
if (options & Verbose)
- printOut(QObject::tr("Stripping non plural forms in '%1'...\n").arg(fn));
+ printOut(LU::tr("Stripping non plural forms in '%1'...\n").arg(fn));
out.stripNonPluralForms();
}
if (options & NoObsolete)
@@ -208,11 +212,11 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
out.normalizeTranslations(cd);
if (!cd.errors().isEmpty()) {
- printErr(cd.error());
+ printOut(cd.error());
cd.clearErrors();
}
if (!out.save(fileName, cd, QLatin1String("auto"))) {
- printErr(cd.error());
+ printOut(cd.error());
*fail = true;
}
}
@@ -267,6 +271,8 @@ static void processSources(Translator &fetchedTor,
else if (it->endsWith(QLatin1String(".js"), Qt::CaseInsensitive)
|| it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive))
loadQScript(fetchedTor, *it, cd);
+ else if (it->endsWith(QLatin1String(".qml"), Qt::CaseInsensitive))
+ loadQml(fetchedTor, *it, cd);
else
sourceFilesCpp << *it;
}
@@ -292,8 +298,9 @@ static void processProject(
if (!tmp.isEmpty()) {
codecForSource = tmp.last().toLatin1();
if (!QTextCodec::codecForName(codecForSource)) {
- qWarning("lupdate warning: Codec for source '%s' is invalid. "
- "Falling back to codec for tr().", codecForSource.constData());
+ printOut(LU::tr("lupdate warning: Codec for source '%1' is invalid."
+ " Falling back to codec for tr().\n")
+ .arg(QString::fromLatin1(codecForSource)));
codecForSource.clear();
}
}
@@ -343,6 +350,10 @@ static void processProjects(
ProFileEvaluator visitor;
visitor.setVerbose(options & Verbose);
+ QHash<QString, QStringList> lupdateConfig;
+ lupdateConfig.insert(QLatin1String("CONFIG"), QStringList(QLatin1String("lupdate_run")));
+ visitor.addVariables(lupdateConfig);
+
QFileInfo pfi(proFile);
ProFile pro(pfi.absoluteFilePath());
if (!visitor.queryProFile(&pro) || !visitor.accept(&pro)) {
@@ -354,12 +365,12 @@ static void processProjects(
if (visitor.contains(QLatin1String("TRANSLATIONS"))) {
if (parentTor) {
if (topLevel) {
- std::cerr << "lupdate warning: TS files from command line "
- "will override TRANSLATIONS in " << qPrintable(proFile) << ".\n";
+ std::cerr << qPrintable(LU::tr("lupdate warning: TS files from command line "
+ "will override TRANSLATIONS in %1.\n").arg(proFile));
goto noTrans;
} else if (nestComplain) {
- std::cerr << "lupdate warning: TS files from command line "
- "prevent recursing into " << qPrintable(proFile) << ".\n";
+ std::cerr << qPrintable(LU::tr("lupdate warning: TS files from command line "
+ "prevent recursing into %1.\n").arg(proFile));
continue;
}
}
@@ -390,8 +401,8 @@ static void processProjects(
noTrans:
if (!parentTor) {
if (topLevel)
- std::cerr << "lupdate warning: no TS files specified. Only diagnostics "
- "will be produced for '" << qPrintable(proFile) << "'.\n";
+ std::cerr << qPrintable(LU::tr("lupdate warning: no TS files specified. Only diagnostics "
+ "will be produced for '%1'.\n").arg(proFile));
Translator tor;
processProject(nestComplain, pfi, visitor, options, codecForSource,
targetLanguage, sourceLanguage, &tor, fail);
@@ -405,7 +416,19 @@ static void processProjects(
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
- m_defaultExtensions = QLatin1String("ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx");
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+#endif // Q_OS_WIN32
+
+ m_defaultExtensions = QLatin1String("java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml");
QStringList args = app.arguments();
QStringList tsFileNames;
@@ -448,7 +471,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-target-language")) {
++i;
if (i == argc) {
- qWarning("The option -target-language requires a parameter.");
+ printOut(LU::tr("The option -target-language requires a parameter.\n"));
return 1;
}
targetLanguage = args[i];
@@ -456,7 +479,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-source-language")) {
++i;
if (i == argc) {
- qWarning("The option -source-language requires a parameter.");
+ printOut(LU::tr("The option -source-language requires a parameter.\n"));
return 1;
}
sourceLanguage = args[i];
@@ -464,7 +487,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-disable-heuristic")) {
++i;
if (i == argc) {
- qWarning("The option -disable-heuristic requires a parameter.");
+ printOut(LU::tr("The option -disable-heuristic requires a parameter.\n"));
return 1;
}
arg = args[i];
@@ -475,14 +498,14 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("number")) {
options &= ~HeuristicNumber;
} else {
- qWarning("Invalid heuristic name passed to -disable-heuristic.");
+ printOut(LU::tr("Invalid heuristic name passed to -disable-heuristic.\n"));
return 1;
}
continue;
} else if (arg == QLatin1String("-locations")) {
++i;
if (i == argc) {
- qWarning("The option -locations requires a parameter.");
+ printOut(LU::tr("The option -locations requires a parameter.\n"));
return 1;
}
if (args[i] == QLatin1String("none")) {
@@ -492,7 +515,7 @@ int main(int argc, char **argv)
} else if (args[i] == QLatin1String("absolute")) {
options |= AbsoluteLocations;
} else {
- qWarning("Invalid parameter passed to -locations.");
+ printOut(LU::tr("Invalid parameter passed to -locations.\n"));
return 1;
}
continue;
@@ -518,7 +541,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-codecfortr")) {
++i;
if (i == argc) {
- qWarning("The -codecfortr option should be followed by a codec name.");
+ printOut(LU::tr("The -codecfortr option should be followed by a codec name.\n"));
return 1;
}
codecForTr = args[i].toLatin1();
@@ -529,7 +552,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-extensions")) {
++i;
if (i == argc) {
- qWarning("The -extensions option should be followed by an extension list.");
+ printOut(LU::tr("The -extensions option should be followed by an extension list.\n"));
return 1;
}
extensions = args[i];
@@ -537,7 +560,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-pro")) {
++i;
if (i == argc) {
- qWarning("The -pro option should be followed by a filename of .pro file.");
+ printOut(LU::tr("The -pro option should be followed by a filename of .pro file.\n"));
return 1;
}
proFiles += args[i];
@@ -547,7 +570,7 @@ int main(int argc, char **argv)
if (arg.length() == 2) {
++i;
if (i == argc) {
- qWarning("The -I option should be followed by a path.");
+ printOut(LU::tr("The -I option should be followed by a path.\n"));
return 1;
}
includePath += args[i];
@@ -556,78 +579,98 @@ int main(int argc, char **argv)
}
continue;
} else if (arg.startsWith(QLatin1String("-")) && arg != QLatin1String("-")) {
- qWarning("Unrecognized option '%s'", qPrintable(arg));
+ printOut(LU::tr("Unrecognized option '%1'.\n").arg(arg));
return 1;
}
+ QStringList files;
+ if (arg.startsWith(QLatin1String("@"))) {
+ QFile lstFile(arg.mid(1));
+ if (!lstFile.open(QIODevice::ReadOnly)) {
+ printOut(LU::tr("lupdate error: List file '%1' is not readable.\n")
+ .arg(lstFile.fileName()));
+ return 1;
+ }
+ while (!lstFile.atEnd())
+ files << QString::fromLocal8Bit(lstFile.readLine().trimmed());
+ } else {
+ files << arg;
+ }
if (metTsFlag) {
- bool found = false;
- foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) {
- if (arg.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) {
- QFileInfo fi(arg);
- if (!fi.exists() || fi.isWritable()) {
- tsFileNames.append(QFileInfo(arg).absoluteFilePath());
- } else {
- qWarning("lupdate warning: For some reason, '%s' is not writable.\n",
- qPrintable(arg));
+ foreach (const QString &file, files) {
+ bool found = false;
+ foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) {
+ if (file.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) {
+ QFileInfo fi(file);
+ if (!fi.exists() || fi.isWritable()) {
+ tsFileNames.append(QFileInfo(file).absoluteFilePath());
+ } else {
+ printOut(LU::tr("lupdate warning: For some reason, '%1' is not writable.\n")
+ .arg(file));
+ }
+ found = true;
+ break;
}
- found = true;
- break;
+ }
+ if (!found) {
+ printOut(LU::tr("lupdate error: File '%1' has no recognized extension.\n")
+ .arg(file));
+ return 1;
}
}
- if (!found) {
- qWarning("lupdate error: File '%s' has no recognized extension\n",
- qPrintable(arg));
- return 1;
- }
- } else if (arg.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
- || arg.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
- proFiles << arg;
numFiles++;
} else {
- QFileInfo fi(arg);
- if (!fi.exists()) {
- qWarning("lupdate error: File '%s' does not exists\n", qPrintable(arg));
- return 1;
- } else if (fi.isDir()) {
- if (options & Verbose)
- printOut(QObject::tr("Scanning directory '%1'...").arg(arg));
- QDir dir = QDir(fi.filePath());
- projectRoots.insert(dir.absolutePath() + QLatin1Char('/'));
- if (extensionsNameFilters.isEmpty()) {
- foreach (QString ext, extensions.split(QLatin1Char(','))) {
- ext = ext.trimmed();
- if (ext.startsWith(QLatin1Char('.')))
- ext.remove(0, 1);
- extensionsNameFilters.insert(ext);
- }
+ foreach (const QString &file, files) {
+ QFileInfo fi(file);
+ if (!fi.exists()) {
+ printOut(LU::tr("lupdate error: File '%1' does not exist.\n").arg(file));
+ return 1;
}
- QDir::Filters filters = QDir::Files | QDir::NoSymLinks;
- if (recursiveScan)
- filters |= QDir::AllDirs | QDir::NoDotAndDotDot;
- QFileInfoList fileinfolist;
- recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist);
- int scanRootLen = dir.absolutePath().length();
- foreach (const QFileInfo &fi, fileinfolist) {
- QString fn = QDir::cleanPath(fi.absoluteFilePath());
- sourceFiles << fn;
-
- if (!fn.endsWith(QLatin1String(".java"))
- && !fn.endsWith(QLatin1String(".ui"))
- && !fn.endsWith(QLatin1String(".js"))
- && !fn.endsWith(QLatin1String(".qs"))) {
- int offset = 0;
- int depth = 0;
- do {
- offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1);
- QString ffn = fn.mid(offset + 1);
- allCSources.insert(ffn, fn);
- } while (++depth < 3 && offset > scanRootLen);
+ if (file.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
+ || file.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
+ proFiles << file;
+ } else if (fi.isDir()) {
+ if (options & Verbose)
+ printOut(LU::tr("Scanning directory '%1'...\n").arg(file));
+ QDir dir = QDir(fi.filePath());
+ projectRoots.insert(dir.absolutePath() + QLatin1Char('/'));
+ if (extensionsNameFilters.isEmpty()) {
+ foreach (QString ext, extensions.split(QLatin1Char(','))) {
+ ext = ext.trimmed();
+ if (ext.startsWith(QLatin1Char('.')))
+ ext.remove(0, 1);
+ extensionsNameFilters.insert(ext);
+ }
}
+ QDir::Filters filters = QDir::Files | QDir::NoSymLinks;
+ if (recursiveScan)
+ filters |= QDir::AllDirs | QDir::NoDotAndDotDot;
+ QFileInfoList fileinfolist;
+ recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist);
+ int scanRootLen = dir.absolutePath().length();
+ foreach (const QFileInfo &fi, fileinfolist) {
+ QString fn = QDir::cleanPath(fi.absoluteFilePath());
+ sourceFiles << fn;
+
+ if (!fn.endsWith(QLatin1String(".java"))
+ && !fn.endsWith(QLatin1String(".jui"))
+ && !fn.endsWith(QLatin1String(".ui"))
+ && !fn.endsWith(QLatin1String(".js"))
+ && !fn.endsWith(QLatin1String(".qs"))
+ && !fn.endsWith(QLatin1String(".qml"))) {
+ int offset = 0;
+ int depth = 0;
+ do {
+ offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1);
+ QString ffn = fn.mid(offset + 1);
+ allCSources.insert(ffn, fn);
+ } while (++depth < 3 && offset > scanRootLen);
+ }
+ }
+ } else {
+ sourceFiles << QDir::cleanPath(fi.absoluteFilePath());;
+ projectRoots.insert(fi.absolutePath() + QLatin1Char('/'));
}
- } else {
- sourceFiles << QDir::cleanPath(fi.absoluteFilePath());;
- projectRoots.insert(fi.absolutePath() + QLatin1Char('/'));
}
numFiles++;
}
@@ -639,16 +682,16 @@ int main(int argc, char **argv)
}
if (!targetLanguage.isEmpty() && tsFileNames.count() != 1)
- std::cerr << "lupdate warning: -target-language usually only "
- "makes sense with exactly one TS file.\n";
+ printOut(LU::tr("lupdate warning: -target-language usually only"
+ " makes sense with exactly one TS file.\n"));
if (!codecForTr.isEmpty() && tsFileNames.isEmpty())
- std::cerr << "lupdate warning: -codecfortr has no effect without -ts.\n";
+ printOut(LU::tr("lupdate warning: -codecfortr has no effect without -ts.\n"));
bool fail = false;
if (proFiles.isEmpty()) {
if (tsFileNames.isEmpty())
- std::cerr << "lupdate warning: no TS files specified. "
- "Only diagnostics will be produced.\n";
+ printOut(LU::tr("lupdate warning:"
+ " no TS files specified. Only diagnostics will be produced.\n"));
Translator fetchedTor;
ConversionData cd;
@@ -662,7 +705,8 @@ int main(int argc, char **argv)
sourceLanguage, targetLanguage, options, &fail);
} else {
if (!sourceFiles.isEmpty() || !includePath.isEmpty()) {
- qWarning("lupdate error: Both project and source files / include paths specified.\n");
+ printOut(LU::tr("lupdate error:"
+ " Both project and source files / include paths specified.\n"));
return 1;
}
if (!tsFileNames.isEmpty()) {