Changeset 846 for trunk/tools/linguist/lupdate/main.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/tools/linguist/lupdate/main.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 53 53 #include <QtCore/QStringList> 54 54 #include <QtCore/QTextCodec> 55 #include <QtCore/QTranslator> 56 #include <QtCore/QLibraryInfo> 55 57 56 58 #include <iostream> … … 58 60 static QString m_defaultExtensions; 59 61 60 static void printErr(const QString & out)61 {62 qWarning("%s", qPrintable(out));63 }64 65 62 static void printOut(const QString & out) 66 63 { 67 64 std::cerr << qPrintable(out); 68 65 } 66 67 class LU { 68 Q_DECLARE_TR_FUNCTIONS(LUpdate) 69 }; 69 70 70 71 static void recursiveFileInfoList(const QDir &dir, … … 81 82 static void printUsage() 82 83 { 83 printOut( QObject::tr(84 printOut(LU::tr( 84 85 "Usage:\n" 85 86 " lupdate [options] [project-file]...\n" 86 " lupdate [options] [source-file|path ]... -ts ts-files\n\n"87 " lupdate [options] [source-file|path|@lst-file]... -ts ts-files|@lst-file\n\n" 87 88 "lupdate is part of Qt's Linguist tool chain. It extracts translatable\n" 88 89 "messages from Qt UI files, C++, Java and JavaScript/QtScript source code.\n" … … 133 134 " -version\n" 134 135 " Display the version of lupdate and exit.\n" 136 " @lst-file\n" 137 " Read additional file names (one per line) from lst-file.\n" 135 138 ).arg(m_defaultExtensions)); 136 139 } … … 149 152 if (QFile(fileName).exists()) { 150 153 if (!tor.load(fileName, cd, QLatin1String("auto"))) { 151 print Err(cd.error());154 printOut(cd.error()); 152 155 *fail = true; 153 156 continue; … … 156 159 cd.clearErrors(); 157 160 if (setCodec && fetchedTor.codec() != tor.codec()) 158 qWarning("lupdate warning: Codec for tr() '%s' disagrees with " 159 "existing file's codec '%s'. Expect trouble.", 160 fetchedTor.codecName().constData(), tor.codecName().constData()); 161 printOut(LU::tr("lupdate warning: Codec for tr() '%1' disagrees with" 162 " existing file's codec '%2'. Expect trouble.\n") 163 .arg(QString::fromLatin1(fetchedTor.codecName()), 164 QString::fromLatin1(tor.codecName()))); 161 165 if (!targetLanguage.isEmpty() && targetLanguage != tor.languageCode()) 162 qWarning("lupdate warning: Specified target language '%s' disagrees with"163 "existing file's language '%s'. Ignoring.",164 qPrintable(targetLanguage), qPrintable(tor.languageCode()));166 printOut(LU::tr("lupdate warning: Specified target language '%1' disagrees with" 167 " existing file's language '%2'. Ignoring.\n") 168 .arg(targetLanguage, tor.languageCode())); 165 169 if (!sourceLanguage.isEmpty() && sourceLanguage != tor.sourceLanguageCode()) 166 qWarning("lupdate warning: Specified source language '%s' disagrees with"167 "existing file's language '%s'. Ignoring.",168 qPrintable(sourceLanguage), qPrintable(tor.sourceLanguageCode()));170 printOut(LU::tr("lupdate warning: Specified source language '%1' disagrees with" 171 " existing file's language '%2'. Ignoring.\n") 172 .arg(sourceLanguage, tor.sourceLanguageCode())); 169 173 } else { 170 174 if (setCodec) … … 185 189 tor.setLocationsType(Translator::AbsoluteLocations); 186 190 if (options & Verbose) 187 printOut( QObject::tr("Updating '%1'...\n").arg(fn));191 printOut(LU::tr("Updating '%1'...\n").arg(fn)); 188 192 189 193 UpdateOptions theseOptions = options; … … 200 204 if (options & PluralOnly) { 201 205 if (options & Verbose) 202 printOut( QObject::tr("Stripping non plural forms in '%1'...\n").arg(fn));206 printOut(LU::tr("Stripping non plural forms in '%1'...\n").arg(fn)); 203 207 out.stripNonPluralForms(); 204 208 } … … 209 213 out.normalizeTranslations(cd); 210 214 if (!cd.errors().isEmpty()) { 211 print Err(cd.error());215 printOut(cd.error()); 212 216 cd.clearErrors(); 213 217 } 214 218 if (!out.save(fileName, cd, QLatin1String("auto"))) { 215 print Err(cd.error());219 printOut(cd.error()); 216 220 *fail = true; 217 221 } … … 268 272 || it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive)) 269 273 loadQScript(fetchedTor, *it, cd); 274 else if (it->endsWith(QLatin1String(".qml"), Qt::CaseInsensitive)) 275 loadQml(fetchedTor, *it, cd); 270 276 else 271 277 sourceFilesCpp << *it; … … 293 299 codecForSource = tmp.last().toLatin1(); 294 300 if (!QTextCodec::codecForName(codecForSource)) { 295 qWarning("lupdate warning: Codec for source '%s' is invalid. " 296 "Falling back to codec for tr().", codecForSource.constData()); 301 printOut(LU::tr("lupdate warning: Codec for source '%1' is invalid." 302 " Falling back to codec for tr().\n") 303 .arg(QString::fromLatin1(codecForSource))); 297 304 codecForSource.clear(); 298 305 } … … 344 351 visitor.setVerbose(options & Verbose); 345 352 353 QHash<QString, QStringList> lupdateConfig; 354 lupdateConfig.insert(QLatin1String("CONFIG"), QStringList(QLatin1String("lupdate_run"))); 355 visitor.addVariables(lupdateConfig); 356 346 357 QFileInfo pfi(proFile); 347 358 ProFile pro(pfi.absoluteFilePath()); … … 355 366 if (parentTor) { 356 367 if (topLevel) { 357 std::cerr << "lupdate warning: TS files from command line "358 "will override TRANSLATIONS in " << qPrintable(proFile) << ".\n";368 std::cerr << qPrintable(LU::tr("lupdate warning: TS files from command line " 369 "will override TRANSLATIONS in %1.\n").arg(proFile)); 359 370 goto noTrans; 360 371 } else if (nestComplain) { 361 std::cerr << "lupdate warning: TS files from command line "362 "prevent recursing into " << qPrintable(proFile) << ".\n";372 std::cerr << qPrintable(LU::tr("lupdate warning: TS files from command line " 373 "prevent recursing into %1.\n").arg(proFile)); 363 374 continue; 364 375 } … … 391 402 if (!parentTor) { 392 403 if (topLevel) 393 std::cerr << "lupdate warning: no TS files specified. Only diagnostics "394 "will be produced for '" << qPrintable(proFile) << "'.\n";404 std::cerr << qPrintable(LU::tr("lupdate warning: no TS files specified. Only diagnostics " 405 "will be produced for '%1'.\n").arg(proFile)); 395 406 Translator tor; 396 407 processProject(nestComplain, pfi, visitor, options, codecForSource, … … 406 417 { 407 418 QCoreApplication app(argc, argv); 408 m_defaultExtensions = QLatin1String("ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx"); 419 #ifndef Q_OS_WIN32 420 QTranslator translator; 421 QTranslator qtTranslator; 422 QString sysLocale = QLocale::system().name(); 423 QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath); 424 if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir) 425 && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) { 426 app.installTranslator(&translator); 427 app.installTranslator(&qtTranslator); 428 } 429 #endif // Q_OS_WIN32 430 431 m_defaultExtensions = QLatin1String("java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml"); 409 432 410 433 QStringList args = app.arguments(); … … 449 472 ++i; 450 473 if (i == argc) { 451 qWarning("The option -target-language requires a parameter.");474 printOut(LU::tr("The option -target-language requires a parameter.\n")); 452 475 return 1; 453 476 } … … 457 480 ++i; 458 481 if (i == argc) { 459 qWarning("The option -source-language requires a parameter.");482 printOut(LU::tr("The option -source-language requires a parameter.\n")); 460 483 return 1; 461 484 } … … 465 488 ++i; 466 489 if (i == argc) { 467 qWarning("The option -disable-heuristic requires a parameter.");490 printOut(LU::tr("The option -disable-heuristic requires a parameter.\n")); 468 491 return 1; 469 492 } … … 476 499 options &= ~HeuristicNumber; 477 500 } else { 478 qWarning("Invalid heuristic name passed to -disable-heuristic.");501 printOut(LU::tr("Invalid heuristic name passed to -disable-heuristic.\n")); 479 502 return 1; 480 503 } … … 483 506 ++i; 484 507 if (i == argc) { 485 qWarning("The option -locations requires a parameter.");508 printOut(LU::tr("The option -locations requires a parameter.\n")); 486 509 return 1; 487 510 } … … 493 516 options |= AbsoluteLocations; 494 517 } else { 495 qWarning("Invalid parameter passed to -locations.");518 printOut(LU::tr("Invalid parameter passed to -locations.\n")); 496 519 return 1; 497 520 } … … 519 542 ++i; 520 543 if (i == argc) { 521 qWarning("The -codecfortr option should be followed by a codec name.");544 printOut(LU::tr("The -codecfortr option should be followed by a codec name.\n")); 522 545 return 1; 523 546 } … … 530 553 ++i; 531 554 if (i == argc) { 532 qWarning("The -extensions option should be followed by an extension list.");555 printOut(LU::tr("The -extensions option should be followed by an extension list.\n")); 533 556 return 1; 534 557 } … … 538 561 ++i; 539 562 if (i == argc) { 540 qWarning("The -pro option should be followed by a filename of .pro file.");563 printOut(LU::tr("The -pro option should be followed by a filename of .pro file.\n")); 541 564 return 1; 542 565 } … … 548 571 ++i; 549 572 if (i == argc) { 550 qWarning("The -I option should be followed by a path.");573 printOut(LU::tr("The -I option should be followed by a path.\n")); 551 574 return 1; 552 575 } … … 557 580 continue; 558 581 } else if (arg.startsWith(QLatin1String("-")) && arg != QLatin1String("-")) { 559 qWarning("Unrecognized option '%s'", qPrintable(arg));582 printOut(LU::tr("Unrecognized option '%1'.\n").arg(arg)); 560 583 return 1; 561 584 } 562 585 586 QStringList files; 587 if (arg.startsWith(QLatin1String("@"))) { 588 QFile lstFile(arg.mid(1)); 589 if (!lstFile.open(QIODevice::ReadOnly)) { 590 printOut(LU::tr("lupdate error: List file '%1' is not readable.\n") 591 .arg(lstFile.fileName())); 592 return 1; 593 } 594 while (!lstFile.atEnd()) 595 files << QString::fromLocal8Bit(lstFile.readLine().trimmed()); 596 } else { 597 files << arg; 598 } 563 599 if (metTsFlag) { 564 bool found = false; 565 foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) { 566 if (arg.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) { 567 QFileInfo fi(arg); 568 if (!fi.exists() || fi.isWritable()) { 569 tsFileNames.append(QFileInfo(arg).absoluteFilePath()); 570 } else { 571 qWarning("lupdate warning: For some reason, '%s' is not writable.\n", 572 qPrintable(arg)); 600 foreach (const QString &file, files) { 601 bool found = false; 602 foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) { 603 if (file.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) { 604 QFileInfo fi(file); 605 if (!fi.exists() || fi.isWritable()) { 606 tsFileNames.append(QFileInfo(file).absoluteFilePath()); 607 } else { 608 printOut(LU::tr("lupdate warning: For some reason, '%1' is not writable.\n") 609 .arg(file)); 610 } 611 found = true; 612 break; 573 613 } 574 found = true;575 break;576 614 } 577 } 578 if (!found) { 579 qWarning("lupdate error: File '%s' has no recognized extension\n", 580 qPrintable(arg)); 581 return 1; 582 } 583 } else if (arg.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive) 584 || arg.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) { 585 proFiles << arg; 615 if (!found) { 616 printOut(LU::tr("lupdate error: File '%1' has no recognized extension.\n") 617 .arg(file)); 618 return 1; 619 } 620 } 586 621 numFiles++; 587 622 } else { 588 QFileInfo fi(arg); 589 if (!fi.exists()) { 590 qWarning("lupdate error: File '%s' does not exists\n", qPrintable(arg)); 591 return 1; 592 } else if (fi.isDir()) { 593 if (options & Verbose) 594 printOut(QObject::tr("Scanning directory '%1'...").arg(arg)); 595 QDir dir = QDir(fi.filePath()); 596 projectRoots.insert(dir.absolutePath() + QLatin1Char('/')); 597 if (extensionsNameFilters.isEmpty()) { 598 foreach (QString ext, extensions.split(QLatin1Char(','))) { 599 ext = ext.trimmed(); 600 if (ext.startsWith(QLatin1Char('.'))) 601 ext.remove(0, 1); 602 extensionsNameFilters.insert(ext); 623 foreach (const QString &file, files) { 624 QFileInfo fi(file); 625 if (!fi.exists()) { 626 printOut(LU::tr("lupdate error: File '%1' does not exist.\n").arg(file)); 627 return 1; 628 } 629 if (file.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive) 630 || file.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) { 631 proFiles << file; 632 } else if (fi.isDir()) { 633 if (options & Verbose) 634 printOut(LU::tr("Scanning directory '%1'...\n").arg(file)); 635 QDir dir = QDir(fi.filePath()); 636 projectRoots.insert(dir.absolutePath() + QLatin1Char('/')); 637 if (extensionsNameFilters.isEmpty()) { 638 foreach (QString ext, extensions.split(QLatin1Char(','))) { 639 ext = ext.trimmed(); 640 if (ext.startsWith(QLatin1Char('.'))) 641 ext.remove(0, 1); 642 extensionsNameFilters.insert(ext); 643 } 603 644 } 645 QDir::Filters filters = QDir::Files | QDir::NoSymLinks; 646 if (recursiveScan) 647 filters |= QDir::AllDirs | QDir::NoDotAndDotDot; 648 QFileInfoList fileinfolist; 649 recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist); 650 int scanRootLen = dir.absolutePath().length(); 651 foreach (const QFileInfo &fi, fileinfolist) { 652 QString fn = QDir::cleanPath(fi.absoluteFilePath()); 653 sourceFiles << fn; 654 655 if (!fn.endsWith(QLatin1String(".java")) 656 && !fn.endsWith(QLatin1String(".jui")) 657 && !fn.endsWith(QLatin1String(".ui")) 658 && !fn.endsWith(QLatin1String(".js")) 659 && !fn.endsWith(QLatin1String(".qs")) 660 && !fn.endsWith(QLatin1String(".qml"))) { 661 int offset = 0; 662 int depth = 0; 663 do { 664 offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1); 665 QString ffn = fn.mid(offset + 1); 666 allCSources.insert(ffn, fn); 667 } while (++depth < 3 && offset > scanRootLen); 668 } 669 } 670 } else { 671 sourceFiles << QDir::cleanPath(fi.absoluteFilePath());; 672 projectRoots.insert(fi.absolutePath() + QLatin1Char('/')); 604 673 } 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 674 } 631 675 numFiles++; … … 639 683 640 684 if (!targetLanguage.isEmpty() && tsFileNames.count() != 1) 641 std::cerr << "lupdate warning: -target-language usually only"642 "makes sense with exactly one TS file.\n";685 printOut(LU::tr("lupdate warning: -target-language usually only" 686 " makes sense with exactly one TS file.\n")); 643 687 if (!codecForTr.isEmpty() && tsFileNames.isEmpty()) 644 std::cerr << "lupdate warning: -codecfortr has no effect without -ts.\n";688 printOut(LU::tr("lupdate warning: -codecfortr has no effect without -ts.\n")); 645 689 646 690 bool fail = false; 647 691 if (proFiles.isEmpty()) { 648 692 if (tsFileNames.isEmpty()) 649 std::cerr << "lupdate warning: no TS files specified."650 "Only diagnostics will be produced.\n";693 printOut(LU::tr("lupdate warning:" 694 " no TS files specified. Only diagnostics will be produced.\n")); 651 695 652 696 Translator fetchedTor; … … 662 706 } else { 663 707 if (!sourceFiles.isEmpty() || !includePath.isEmpty()) { 664 qWarning("lupdate error: Both project and source files / include paths specified.\n"); 708 printOut(LU::tr("lupdate error:" 709 " Both project and source files / include paths specified.\n")); 665 710 return 1; 666 711 }
Note:
See TracChangeset
for help on using the changeset viewer.