Changeset 651 for trunk/tools/linguist/lupdate/main.cpp
- Timestamp:
- Mar 8, 2010, 12:52:58 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.6.2 (added) merged: 650 /branches/vendor/nokia/qt/current merged: 649 /branches/vendor/nokia/qt/4.6.1 removed
- Property svn:mergeinfo changed
-
trunk/tools/linguist/lupdate/main.cpp
r561 r651 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 20 09Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 #include <translator.h> 45 45 #include <profileevaluator.h> 46 #include <proreader.h>47 46 48 47 #include <QtCore/QCoreApplication> … … 119 118 " Disable the named merge heuristic. Can be specified multiple times.\n" 120 119 " -pro <filename>\n" 121 " Name of a .pro file. Useful for files with .pro \n"122 " file syntax but different file suffix\n"120 " Name of a .pro file. Useful for files with .pro file syntax but\n" 121 " different file suffix. Projects are recursed into and merged.\n" 123 122 " -source-language <language>[_<region>]\n" 124 123 " Specify the language of the source strings for new files.\n" … … 127 126 " Specify the language of the translations for new files.\n" 128 127 " Guessed from the file name if not specified.\n" 128 " -ts <ts-file>...\n" 129 " Specify the output file(s). This will override the TRANSLATIONS\n" 130 " and nullify the CODECFORTR from possibly specified project files.\n" 131 " -codecfortr <codec>\n" 132 " Specify the codec assumed for tr() calls. Effective only with -ts.\n" 129 133 " -version\n" 130 134 " Display the version of lupdate and exit.\n" … … 215 219 } 216 220 221 static QStringList getSources(const char *var, const char *vvar, const QStringList &baseVPaths, 222 const QString &projectDir, const ProFileEvaluator &visitor) 223 { 224 QStringList vPaths = visitor.absolutePathValues(QLatin1String(vvar), projectDir); 225 vPaths += baseVPaths; 226 vPaths.removeDuplicates(); 227 return visitor.absoluteFileValues(QLatin1String(var), projectDir, vPaths, 0); 228 } 229 230 static QStringList getSources(const ProFileEvaluator &visitor, const QString &projectDir) 231 { 232 QStringList baseVPaths; 233 baseVPaths += visitor.absolutePathValues(QLatin1String("VPATH"), projectDir); 234 baseVPaths << projectDir; // QMAKE_ABSOLUTE_SOURCE_PATH 235 baseVPaths += visitor.absolutePathValues(QLatin1String("DEPENDPATH"), projectDir); 236 baseVPaths.removeDuplicates(); 237 238 QStringList sourceFiles; 239 240 // app/lib template 241 sourceFiles += getSources("SOURCES", "VPATH_SOURCES", baseVPaths, projectDir, visitor); 242 243 sourceFiles += getSources("FORMS", "VPATH_FORMS", baseVPaths, projectDir, visitor); 244 sourceFiles += getSources("FORMS3", "VPATH_FORMS3", baseVPaths, projectDir, visitor); 245 246 QStringList vPathsInc = baseVPaths; 247 vPathsInc += visitor.absolutePathValues(QLatin1String("INCLUDEPATH"), projectDir); 248 vPathsInc.removeDuplicates(); 249 sourceFiles += visitor.absoluteFileValues(QLatin1String("HEADERS"), projectDir, vPathsInc, 0); 250 251 sourceFiles.removeDuplicates(); 252 sourceFiles.sort(); 253 254 return sourceFiles; 255 } 256 257 static void processSources(Translator &fetchedTor, 258 const QStringList &sourceFiles, ConversionData &cd) 259 { 260 QStringList sourceFilesCpp; 261 for (QStringList::const_iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) { 262 if (it->endsWith(QLatin1String(".java"), Qt::CaseInsensitive)) 263 loadJava(fetchedTor, *it, cd); 264 else if (it->endsWith(QLatin1String(".ui"), Qt::CaseInsensitive) 265 || it->endsWith(QLatin1String(".jui"), Qt::CaseInsensitive)) 266 loadUI(fetchedTor, *it, cd); 267 else if (it->endsWith(QLatin1String(".js"), Qt::CaseInsensitive) 268 || it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive)) 269 loadQScript(fetchedTor, *it, cd); 270 else 271 sourceFilesCpp << *it; 272 } 273 loadCPP(fetchedTor, sourceFilesCpp, cd); 274 if (!cd.error().isEmpty()) 275 printOut(cd.error()); 276 } 277 278 static void processProjects( 279 bool topLevel, bool nestComplain, const QStringList &proFiles, 280 UpdateOptions options, const QByteArray &codecForSource, 281 const QString &targetLanguage, const QString &sourceLanguage, 282 Translator *parentTor, bool *fail); 283 284 static void processProject( 285 bool nestComplain, const QFileInfo &pfi, ProFileEvaluator &visitor, 286 UpdateOptions options, const QByteArray &_codecForSource, 287 const QString &targetLanguage, const QString &sourceLanguage, 288 Translator *fetchedTor, bool *fail) 289 { 290 QByteArray codecForSource = _codecForSource; 291 QStringList tmp = visitor.values(QLatin1String("CODECFORSRC")); 292 if (!tmp.isEmpty()) { 293 codecForSource = tmp.last().toLatin1(); 294 if (!QTextCodec::codecForName(codecForSource)) { 295 qWarning("lupdate warning: Codec for source '%s' is invalid. " 296 "Falling back to codec for tr().", codecForSource.constData()); 297 codecForSource.clear(); 298 } 299 } 300 if (visitor.templateType() == ProFileEvaluator::TT_Subdirs) { 301 QStringList subProFiles; 302 QDir proDir(pfi.absoluteDir()); 303 foreach (const QString &subdir, visitor.values(QLatin1String("SUBDIRS"))) { 304 QString subPro = QDir::cleanPath(proDir.absoluteFilePath(subdir)); 305 QFileInfo subInfo(subPro); 306 if (subInfo.isDir()) 307 subProFiles << (subPro + QLatin1Char('/') 308 + subInfo.fileName() + QLatin1String(".pro")); 309 else 310 subProFiles << subPro; 311 } 312 processProjects(false, nestComplain, subProFiles, options, codecForSource, 313 targetLanguage, sourceLanguage, fetchedTor, fail); 314 } else { 315 ConversionData cd; 316 cd.m_noUiLines = options & NoUiLines; 317 cd.m_codecForSource = codecForSource; 318 cd.m_includePath = visitor.values(QLatin1String("INCLUDEPATH")); 319 QStringList sourceFiles = getSources(visitor, pfi.absolutePath()); 320 QSet<QString> sourceDirs; 321 sourceDirs.insert(QDir::cleanPath(pfi.absolutePath()) + QLatin1Char('/')); 322 foreach (const QString &sf, sourceFiles) 323 sourceDirs.insert(sf.left(sf.lastIndexOf(QLatin1Char('/')) + 1)); 324 QStringList rootList = sourceDirs.toList(); 325 rootList.sort(); 326 for (int prev = 0, curr = 1; curr < rootList.length(); ) 327 if (rootList.at(curr).startsWith(rootList.at(prev))) 328 rootList.removeAt(curr); 329 else 330 prev = curr++; 331 cd.m_projectRoots = QSet<QString>::fromList(rootList); 332 processSources(*fetchedTor, sourceFiles, cd); 333 } 334 } 335 336 static void processProjects( 337 bool topLevel, bool nestComplain, const QStringList &proFiles, 338 UpdateOptions options, const QByteArray &codecForSource, 339 const QString &targetLanguage, const QString &sourceLanguage, 340 Translator *parentTor, bool *fail) 341 { 342 foreach (const QString &proFile, proFiles) { 343 ProFileEvaluator visitor; 344 visitor.setVerbose(options & Verbose); 345 346 QFileInfo pfi(proFile); 347 ProFile pro(pfi.absoluteFilePath()); 348 if (!visitor.queryProFile(&pro) || !visitor.accept(&pro)) { 349 if (topLevel) 350 *fail = true; 351 continue; 352 } 353 354 if (visitor.contains(QLatin1String("TRANSLATIONS"))) { 355 if (parentTor) { 356 if (topLevel) { 357 std::cerr << "lupdate warning: TS files from command line " 358 "will override TRANSLATIONS in " << qPrintable(proFile) << ".\n"; 359 goto noTrans; 360 } else if (nestComplain) { 361 std::cerr << "lupdate warning: TS files from command line " 362 "prevent recursing into " << qPrintable(proFile) << ".\n"; 363 continue; 364 } 365 } 366 QStringList tsFiles; 367 QDir proDir(pfi.absolutePath()); 368 foreach (const QString &tsFile, visitor.values(QLatin1String("TRANSLATIONS"))) 369 tsFiles << QFileInfo(proDir, tsFile).filePath(); 370 if (tsFiles.isEmpty()) { 371 // This might mean either a buggy PRO file or an intentional detach - 372 // we can't know without seeing the actual RHS of the assignment ... 373 // Just assume correctness and be silent. 374 continue; 375 } 376 Translator tor; 377 QByteArray codecForTr; 378 QStringList tmp = visitor.values(QLatin1String("CODEC")) 379 + visitor.values(QLatin1String("DEFAULTCODEC")) 380 + visitor.values(QLatin1String("CODECFORTR")); 381 if (!tmp.isEmpty()) { 382 codecForTr = tmp.last().toLatin1(); 383 tor.setCodecName(codecForTr); 384 } 385 processProject(false, pfi, visitor, options, codecForSource, 386 targetLanguage, sourceLanguage, &tor, fail); 387 updateTsFiles(tor, tsFiles, codecForTr, sourceLanguage, targetLanguage, options, fail); 388 continue; 389 } 390 noTrans: 391 if (!parentTor) { 392 if (topLevel) 393 std::cerr << "lupdate warning: no TS files specified. Only diagnostics " 394 "will be produced for '" << qPrintable(proFile) << "'.\n"; 395 Translator tor; 396 processProject(nestComplain, pfi, visitor, options, codecForSource, 397 targetLanguage, sourceLanguage, &tor, fail); 398 } else { 399 processProject(nestComplain, pfi, visitor, options, codecForSource, 400 targetLanguage, sourceLanguage, parentTor, fail); 401 } 402 } 403 } 404 217 405 int main(int argc, char **argv) 218 406 { … … 221 409 222 410 QStringList args = app.arguments(); 223 QString defaultContext; // This was QLatin1String("@default") before.224 Translator fetchedTor;225 QByteArray codecForTr;226 QByteArray codecForSource;227 411 QStringList tsFileNames; 228 412 QStringList proFiles; … … 233 417 QString targetLanguage; 234 418 QString sourceLanguage; 419 QByteArray codecForTr; 235 420 236 421 UpdateOptions options = … … 238 423 HeuristicSameText | HeuristicSimilarText | HeuristicNumber; 239 424 int numFiles = 0; 240 bool standardSyntax = true;241 425 bool metTsFlag = false; 242 426 bool recursiveScan = true; … … 244 428 QString extensions = m_defaultExtensions; 245 429 QSet<QString> extensionsNameFilters; 246 247 for (int i = 1; i < argc; ++i) {248 if (args.at(i) == QLatin1String("-ts"))249 standardSyntax = false;250 }251 430 252 431 for (int i = 1; i < argc; ++i) { … … 337 516 printOut(QObject::tr("lupdate version %1\n").arg(QLatin1String(QT_VERSION_STR))); 338 517 return 0; 518 } else if (arg == QLatin1String("-codecfortr")) { 519 ++i; 520 if (i == argc) { 521 qWarning("The -codecfortr option should be followed by a codec name."); 522 return 1; 523 } 524 codecForTr = args[i].toLatin1(); 525 continue; 339 526 } else if (arg == QLatin1String("-ts")) { 340 527 metTsFlag = true; … … 373 560 return 1; 374 561 } 375 376 numFiles++;377 378 QString fullText;379 380 codecForTr.clear();381 codecForSource.clear();382 562 383 563 if (metTsFlag) { … … 404 584 || arg.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) { 405 585 proFiles << arg; 586 numFiles++; 406 587 } else { 407 588 QFileInfo fi(arg); … … 448 629 sourceFiles << QDir::cleanPath(fi.absoluteFilePath());; 449 630 } 631 numFiles++; 450 632 } 451 633 } // for args 452 634 453 foreach (const QString &proFile, proFiles) 454 projectRoots.insert(QDir::cleanPath(QFileInfo(proFile).absolutePath()) + QLatin1Char('/')); 455 456 bool firstPass = true; 635 if (numFiles == 0) { 636 printUsage(); 637 return 1; 638 } 639 640 if (!targetLanguage.isEmpty() && tsFileNames.count() != 1) 641 std::cerr << "lupdate warning: -target-language usually only " 642 "makes sense with exactly one TS file.\n"; 643 if (!codecForTr.isEmpty() && tsFileNames.isEmpty()) 644 std::cerr << "lupdate warning: -codecfortr has no effect without -ts.\n"; 645 457 646 bool fail = false; 458 while (firstPass || !proFiles.isEmpty()) { 647 if (proFiles.isEmpty()) { 648 if (tsFileNames.isEmpty()) 649 std::cerr << "lupdate warning: no TS files specified. " 650 "Only diagnostics will be produced.\n"; 651 652 Translator fetchedTor; 459 653 ConversionData cd; 460 cd.m_defaultContext = defaultContext;461 654 cd.m_noUiLines = options & NoUiLines; 462 655 cd.m_projectRoots = projectRoots; 463 656 cd.m_includePath = includePath; 464 657 cd.m_allCSources = allCSources; 465 466 QStringList tsFiles = tsFileNames; 467 if (proFiles.count() > 0) { 468 QFileInfo pfi(proFiles.takeFirst()); 469 QHash<QByteArray, QStringList> variables; 470 471 ProFileEvaluator visitor; 472 visitor.setVerbose(options & Verbose); 473 474 ProFile pro(pfi.absoluteFilePath()); 475 if (!visitor.queryProFile(&pro)) 476 return 2; 477 if (!visitor.accept(&pro)) 478 return 2; 479 480 if (visitor.templateType() == ProFileEvaluator::TT_Subdirs) { 481 QDir proDir(pfi.absoluteDir()); 482 foreach (const QString &subdir, visitor.values(QLatin1String("SUBDIRS"))) { 483 QString subPro = QDir::cleanPath(proDir.absoluteFilePath(subdir)); 484 QFileInfo subInfo(subPro); 485 if (subInfo.isDir()) 486 proFiles << (subPro + QLatin1Char('/') 487 + subInfo.fileName() + QLatin1String(".pro")); 488 else 489 proFiles << subPro; 490 } 491 continue; 492 } 493 494 cd.m_includePath += visitor.values(QLatin1String("INCLUDEPATH")); 495 496 evaluateProFile(visitor, &variables, pfi.absolutePath()); 497 498 sourceFiles = variables.value("SOURCES"); 499 500 QStringList tmp = variables.value("CODECFORTR"); 501 if (!tmp.isEmpty() && !tmp.first().isEmpty()) { 502 codecForTr = tmp.first().toLatin1(); 503 fetchedTor.setCodecName(codecForTr); 504 cd.m_outputCodec = codecForTr; 505 } 506 tmp = variables.value("CODECFORSRC"); 507 if (!tmp.isEmpty() && !tmp.first().isEmpty()) { 508 codecForSource = tmp.first().toLatin1(); 509 if (!QTextCodec::codecForName(codecForSource)) 510 qWarning("lupdate warning: Codec for source '%s' is invalid. Falling back to codec for tr().", 511 codecForSource.constData()); 512 else 513 cd.m_codecForSource = codecForSource; 514 } 515 516 tsFiles += variables.value("TRANSLATIONS"); 517 } 518 519 QStringList sourceFilesCpp; 520 for (QStringList::iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) { 521 if (it->endsWith(QLatin1String(".java"), Qt::CaseInsensitive)) 522 loadJava(fetchedTor, *it, cd); 523 else if (it->endsWith(QLatin1String(".ui"), Qt::CaseInsensitive) 524 || it->endsWith(QLatin1String(".jui"), Qt::CaseInsensitive)) 525 loadUI(fetchedTor, *it, cd); 526 else if (it->endsWith(QLatin1String(".js"), Qt::CaseInsensitive) 527 || it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive)) 528 loadQScript(fetchedTor, *it, cd); 529 else 530 sourceFilesCpp << *it; 531 } 532 loadCPP(fetchedTor, sourceFilesCpp, cd); 533 if (!cd.error().isEmpty()) 534 printOut(cd.error()); 535 536 tsFiles.sort(); 537 tsFiles.removeDuplicates(); 538 539 if (!tsFiles.isEmpty()) 540 updateTsFiles(fetchedTor, tsFiles, codecForTr, sourceLanguage, targetLanguage, options, &fail); 541 542 firstPass = false; 658 fetchedTor.setCodecName(codecForTr); 659 processSources(fetchedTor, sourceFiles, cd); 660 updateTsFiles(fetchedTor, tsFileNames, codecForTr, 661 sourceLanguage, targetLanguage, options, &fail); 662 } else { 663 if (!sourceFiles.isEmpty() || !includePath.isEmpty()) { 664 qWarning("lupdate error: Both project and source files / include paths specified.\n"); 665 return 1; 666 } 667 if (!tsFileNames.isEmpty()) { 668 Translator fetchedTor; 669 fetchedTor.setCodecName(codecForTr); 670 processProjects(true, true, proFiles, options, QByteArray(), 671 targetLanguage, sourceLanguage, &fetchedTor, &fail); 672 updateTsFiles(fetchedTor, tsFileNames, codecForTr, 673 sourceLanguage, targetLanguage, options, &fail); 674 } else { 675 processProjects(true, false, proFiles, options, QByteArray(), 676 targetLanguage, sourceLanguage, 0, &fail); 677 } 543 678 } 544 545 if (numFiles == 0) {546 printUsage();547 return 1;548 }549 550 679 return fail ? 1 : 0; 551 680 }
Note:
See TracChangeset
for help on using the changeset viewer.