tools/linguist/lupdate/main.cpp
changeset 30 5dc02b23752f
parent 18 2f34d5167611
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    81 static void printUsage()
    81 static void printUsage()
    82 {
    82 {
    83     printOut(QObject::tr(
    83     printOut(QObject::tr(
    84         "Usage:\n"
    84         "Usage:\n"
    85         "    lupdate [options] [project-file]...\n"
    85         "    lupdate [options] [project-file]...\n"
    86         "    lupdate [options] [source-file|path]... -ts ts-files\n\n"
    86         "    lupdate [options] [source-file|path|@lst-file]... -ts ts-files|@lst-file\n\n"
    87         "lupdate is part of Qt's Linguist tool chain. It extracts translatable\n"
    87         "lupdate is part of Qt's Linguist tool chain. It extracts translatable\n"
    88         "messages from Qt UI files, C++, Java and JavaScript/QtScript source code.\n"
    88         "messages from Qt UI files, C++, Java and JavaScript/QtScript source code.\n"
    89         "Extracted messages are stored in textual translation source files (typically\n"
    89         "Extracted messages are stored in textual translation source files (typically\n"
    90         "Qt TS XML). New and modified messages can be merged into existing TS files.\n\n"
    90         "Qt TS XML). New and modified messages can be merged into existing TS files.\n\n"
    91         "Options:\n"
    91         "Options:\n"
   130         "           and nullify the CODECFORTR from possibly specified project files.\n"
   130         "           and nullify the CODECFORTR from possibly specified project files.\n"
   131         "    -codecfortr <codec>\n"
   131         "    -codecfortr <codec>\n"
   132         "           Specify the codec assumed for tr() calls. Effective only with -ts.\n"
   132         "           Specify the codec assumed for tr() calls. Effective only with -ts.\n"
   133         "    -version\n"
   133         "    -version\n"
   134         "           Display the version of lupdate and exit.\n"
   134         "           Display the version of lupdate and exit.\n"
       
   135         "    @lst-file\n"
       
   136         "           Read additional file names (one per line) from lst-file.\n"
   135     ).arg(m_defaultExtensions));
   137     ).arg(m_defaultExtensions));
   136 }
   138 }
   137 
   139 
   138 static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFileNames,
   140 static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFileNames,
   139     bool setCodec, const QString &sourceLanguage, const QString &targetLanguage,
   141     bool setCodec, const QString &sourceLanguage, const QString &targetLanguage,
   265                  || it->endsWith(QLatin1String(".jui"), Qt::CaseInsensitive))
   267                  || it->endsWith(QLatin1String(".jui"), Qt::CaseInsensitive))
   266             loadUI(fetchedTor, *it, cd);
   268             loadUI(fetchedTor, *it, cd);
   267         else if (it->endsWith(QLatin1String(".js"), Qt::CaseInsensitive)
   269         else if (it->endsWith(QLatin1String(".js"), Qt::CaseInsensitive)
   268                  || it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive))
   270                  || it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive))
   269             loadQScript(fetchedTor, *it, cd);
   271             loadQScript(fetchedTor, *it, cd);
       
   272         else if (it->endsWith(QLatin1String(".qml"), Qt::CaseInsensitive))
       
   273             loadQml(fetchedTor, *it, cd);
   270         else
   274         else
   271             sourceFilesCpp << *it;
   275             sourceFilesCpp << *it;
   272     }
   276     }
   273     loadCPP(fetchedTor, sourceFilesCpp, cd);
   277     loadCPP(fetchedTor, sourceFilesCpp, cd);
   274     if (!cd.error().isEmpty())
   278     if (!cd.error().isEmpty())
   403 }
   407 }
   404 
   408 
   405 int main(int argc, char **argv)
   409 int main(int argc, char **argv)
   406 {
   410 {
   407     QCoreApplication app(argc, argv);
   411     QCoreApplication app(argc, argv);
   408     m_defaultExtensions = QLatin1String("ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx");
   412     m_defaultExtensions = QLatin1String("java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml");
   409 
   413 
   410     QStringList args = app.arguments();
   414     QStringList args = app.arguments();
   411     QStringList tsFileNames;
   415     QStringList tsFileNames;
   412     QStringList proFiles;
   416     QStringList proFiles;
   413     QMultiHash<QString, QString> allCSources;
   417     QMultiHash<QString, QString> allCSources;
   558         } else if (arg.startsWith(QLatin1String("-")) && arg != QLatin1String("-")) {
   562         } else if (arg.startsWith(QLatin1String("-")) && arg != QLatin1String("-")) {
   559             qWarning("Unrecognized option '%s'", qPrintable(arg));
   563             qWarning("Unrecognized option '%s'", qPrintable(arg));
   560             return 1;
   564             return 1;
   561         }
   565         }
   562 
   566 
       
   567         QStringList files;
       
   568         if (arg.startsWith(QLatin1String("@"))) {
       
   569             QFile lstFile(arg.mid(1));
       
   570             if (!lstFile.open(QIODevice::ReadOnly)) {
       
   571                 qWarning("lupdate error: List file '%s' is not readable",
       
   572                          qPrintable(lstFile.fileName()));
       
   573                 return 1;
       
   574             }
       
   575             while (!lstFile.atEnd())
       
   576                 files << QString::fromLocal8Bit(lstFile.readLine().trimmed());
       
   577         } else {
       
   578             files << arg;
       
   579         }
   563         if (metTsFlag) {
   580         if (metTsFlag) {
   564             bool found = false;
   581             foreach (const QString &file, files) {
   565             foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) {
   582                 bool found = false;
   566                 if (arg.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) {
   583                 foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) {
   567                     QFileInfo fi(arg);
   584                     if (file.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) {
   568                     if (!fi.exists() || fi.isWritable()) {
   585                         QFileInfo fi(file);
   569                         tsFileNames.append(QFileInfo(arg).absoluteFilePath());
   586                         if (!fi.exists() || fi.isWritable()) {
   570                     } else {
   587                             tsFileNames.append(QFileInfo(file).absoluteFilePath());
   571                         qWarning("lupdate warning: For some reason, '%s' is not writable.\n",
   588                         } else {
   572                                 qPrintable(arg));
   589                             qWarning("lupdate warning: For some reason, '%s' is not writable.\n",
       
   590                                     qPrintable(file));
       
   591                         }
       
   592                         found = true;
       
   593                         break;
   573                     }
   594                     }
   574                     found = true;
       
   575                     break;
       
   576                 }
   595                 }
   577             }
   596                 if (!found) {
   578             if (!found) {
   597                     qWarning("lupdate error: File '%s' has no recognized extension\n",
   579                 qWarning("lupdate error: File '%s' has no recognized extension\n",
   598                              qPrintable(file));
   580                          qPrintable(arg));
   599                     return 1;
   581                 return 1;
   600                 }
   582             }
   601             }
   583         } else if (arg.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
       
   584                 || arg.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
       
   585             proFiles << arg;
       
   586             numFiles++;
   602             numFiles++;
   587         } else {
   603         } else {
   588             QFileInfo fi(arg);
   604             foreach (const QString &file, files) {
   589             if (!fi.exists()) {
   605                 QFileInfo fi(file);
   590                 qWarning("lupdate error: File '%s' does not exists\n", qPrintable(arg));
   606                 if (!fi.exists()) {
   591                 return 1;
   607                     qWarning("lupdate error: File '%s' does not exists\n", qPrintable(file));
   592             } else if (fi.isDir()) {
   608                     return 1;
   593                 if (options & Verbose)
   609                 }
   594                     printOut(QObject::tr("Scanning directory '%1'...").arg(arg));
   610                 if (file.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
   595                 QDir dir = QDir(fi.filePath());
   611                     || file.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
   596                 projectRoots.insert(dir.absolutePath() + QLatin1Char('/'));
   612                     proFiles << file;
   597                 if (extensionsNameFilters.isEmpty()) {
   613                 } else if (fi.isDir()) {
   598                     foreach (QString ext, extensions.split(QLatin1Char(','))) {
   614                     if (options & Verbose)
   599                         ext = ext.trimmed();
   615                         printOut(QObject::tr("Scanning directory '%1'...").arg(file));
   600                         if (ext.startsWith(QLatin1Char('.')))
   616                     QDir dir = QDir(fi.filePath());
   601                             ext.remove(0, 1);
   617                     projectRoots.insert(dir.absolutePath() + QLatin1Char('/'));
   602                         extensionsNameFilters.insert(ext);
   618                     if (extensionsNameFilters.isEmpty()) {
       
   619                         foreach (QString ext, extensions.split(QLatin1Char(','))) {
       
   620                             ext = ext.trimmed();
       
   621                             if (ext.startsWith(QLatin1Char('.')))
       
   622                                 ext.remove(0, 1);
       
   623                             extensionsNameFilters.insert(ext);
       
   624                         }
   603                     }
   625                     }
       
   626                     QDir::Filters filters = QDir::Files | QDir::NoSymLinks;
       
   627                     if (recursiveScan)
       
   628                         filters |= QDir::AllDirs | QDir::NoDotAndDotDot;
       
   629                     QFileInfoList fileinfolist;
       
   630                     recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist);
       
   631                     int scanRootLen = dir.absolutePath().length();
       
   632                     foreach (const QFileInfo &fi, fileinfolist) {
       
   633                         QString fn = QDir::cleanPath(fi.absoluteFilePath());
       
   634                         sourceFiles << fn;
       
   635 
       
   636                         if (!fn.endsWith(QLatin1String(".java"))
       
   637                             && !fn.endsWith(QLatin1String(".jui"))
       
   638                             && !fn.endsWith(QLatin1String(".ui"))
       
   639                             && !fn.endsWith(QLatin1String(".js"))
       
   640                             && !fn.endsWith(QLatin1String(".qs"))
       
   641                             && !fn.endsWith(QLatin1String(".qml"))) {
       
   642                             int offset = 0;
       
   643                             int depth = 0;
       
   644                             do {
       
   645                                 offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1);
       
   646                                 QString ffn = fn.mid(offset + 1);
       
   647                                 allCSources.insert(ffn, fn);
       
   648                             } while (++depth < 3 && offset > scanRootLen);
       
   649                         }
       
   650                     }
       
   651                 } else {
       
   652                     sourceFiles << QDir::cleanPath(fi.absoluteFilePath());;
   604                 }
   653                 }
   605                 QDir::Filters filters = QDir::Files | QDir::NoSymLinks;
       
   606                 if (recursiveScan)
       
   607                     filters |= QDir::AllDirs | QDir::NoDotAndDotDot;
       
   608                 QFileInfoList fileinfolist;
       
   609                 recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist);
       
   610                 int scanRootLen = dir.absolutePath().length();
       
   611                 foreach (const QFileInfo &fi, fileinfolist) {
       
   612                     QString fn = QDir::cleanPath(fi.absoluteFilePath());
       
   613                     sourceFiles << fn;
       
   614 
       
   615                     if (!fn.endsWith(QLatin1String(".java"))
       
   616                         && !fn.endsWith(QLatin1String(".ui"))
       
   617                         && !fn.endsWith(QLatin1String(".js"))
       
   618                         && !fn.endsWith(QLatin1String(".qs"))) {
       
   619                         int offset = 0;
       
   620                         int depth = 0;
       
   621                         do {
       
   622                             offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1);
       
   623                             QString ffn = fn.mid(offset + 1);
       
   624                             allCSources.insert(ffn, fn);
       
   625                         } while (++depth < 3 && offset > scanRootLen);
       
   626                     }
       
   627                 }
       
   628             } else {
       
   629                 sourceFiles << QDir::cleanPath(fi.absoluteFilePath());;
       
   630             }
   654             }
   631             numFiles++;
   655             numFiles++;
   632         }
   656         }
   633     } // for args
   657     } // for args
   634 
   658