main.cpp 32.54 KiB
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
** $QT_END_LICENSE$
****************************************************************************/
// There must be no #include before this !
#define setlocale locale_file_name_for_clang_qdoc() { \
        static char data[] = __FILE__;           \
        return data;                             \
    }                                            \
    extern char *setlocale
#include <locale.h>
#undef setlocale
#include <qglobal.h>
#include <qhashfunctions.h>
#include <stdlib.h>
#include "codemarker.h"
#include "codeparser.h"
#include "config.h"
#include "cppcodemarker.h"
#include "cppcodeparser.h"
#include "doc.h"
#include "htmlgenerator.h"
#include "location.h"
#include "plaincodemarker.h"
#include "puredocparser.h"
#include "tokenizer.h"
#include "tree.h"
#include "qdocdatabase.h"
#include "jscodemarker.h"
#include "qmlcodemarker.h"
#include "qmlcodeparser.h"
#include "clangcodeparser.h"
#include <qdatetime.h>
#include <qdebug.h>
#include "qtranslator.h"
#ifndef QT_BOOTSTRAPPED
#  include "qcoreapplication.h"
#endif
#include "qcommandlineoption.h"
#include "qcommandlineparser.h"
#include <algorithm>
QT_BEGIN_NAMESPACE
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
bool creationTimeBefore(const QFileInfo &fi1, const QFileInfo &fi2) { return fi1.lastModified() < fi2.lastModified(); } static bool highlighting = false; static bool showInternal = false; static bool singleExec = false; static bool writeQaPages = false; static bool redirectDocumentationToDevNull = false; static bool noLinkErrors = false; static bool autolinkErrors = false; static bool obsoleteLinks = false; static QStringList defines; static QStringList includesPaths; static QStringList dependModules; static QStringList indexDirs; static QString currentDir; static QString prevCurrentDir; static QHash<QString,QString> defaults; #ifndef QT_NO_TRANSLATION typedef QPair<QString, QTranslator*> Translator; static QList<Translator> translators; #endif /*! Read some XML indexes containing definitions from other documentation sets. \a config contains a variable that lists directories where index files can bge found. It also contains the \c depends variable, which lists the modules that the current module depends on. */ static void loadIndexFiles(Config& config) { QDocDatabase* qdb = QDocDatabase::qdocDB(); QStringList indexFiles; QStringList configIndexes = config.getStringList(CONFIG_INDEXES); foreach (const QString &index, configIndexes) { QFileInfo fi(index); if (fi.exists() && fi.isFile()) indexFiles << index; else Location::null.warning(QString("Index file not found: %1").arg(index)); } dependModules += config.getStringList(CONFIG_DEPENDS); dependModules.removeDuplicates(); bool noOutputSubdirs = false; QString singleOutputSubdir; if (config.getBool(QString("HTML.nosubdirs"))) { noOutputSubdirs = true; singleOutputSubdir = config.getString("HTML.outputsubdir"); if (singleOutputSubdir.isEmpty()) singleOutputSubdir = "html"; } if (dependModules.size() > 0) { if (indexDirs.size() > 0) { for (int i = 0; i < indexDirs.size(); i++) { if (indexDirs[i].startsWith("..")) { const QString prefix(QDir(currentDir).relativeFilePath(prevCurrentDir)); if (!prefix.isEmpty()) indexDirs[i].prepend(prefix + QLatin1Char('/')); } } /* Add all subdirectories of the indexdirs as dependModules, when an asterisk is used in the 'depends' list. */
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
if (dependModules.contains("*")) { dependModules.removeOne("*"); for (int i = 0; i < indexDirs.size(); i++) { QDir scanDir = QDir(indexDirs[i]); scanDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); QFileInfoList dirList = scanDir.entryInfoList(); for (int j = 0; j < dirList.size(); j++) { if (dirList[j].fileName().toLower() != config.getString(CONFIG_PROJECT).toLower()) dependModules.append(dirList[j].fileName()); } } } for (int i = 0; i < dependModules.size(); i++) { QString indexToAdd; QList<QFileInfo> foundIndices; for (int j = 0; j < indexDirs.size(); j++) { QString fileToLookFor = indexDirs[j] + QLatin1Char('/'); if (noOutputSubdirs) fileToLookFor += singleOutputSubdir; else fileToLookFor += dependModules[i]; fileToLookFor += QLatin1Char('/') + dependModules[i] + QLatin1String(".index"); if (QFile::exists(fileToLookFor)) { QFileInfo tempFileInfo(fileToLookFor); if (!foundIndices.contains(tempFileInfo)) foundIndices.append(tempFileInfo); } } std::sort(foundIndices.begin(), foundIndices.end(), creationTimeBefore); if (foundIndices.size() > 1) { /* QDoc should always use the last entry in the multimap when there are multiple index files for a module, since the last modified file has the highest UNIX timestamp. */ QStringList indexPaths; for (int k = 0; k < foundIndices.size(); k++) indexPaths << foundIndices[k].absoluteFilePath(); Location::null.warning(QString("Multiple index files found for dependency \"%1\":\n%2").arg( dependModules[i], indexPaths.join('\n'))); Location::null.warning(QString("Using %1 as index file for dependency \"%2\"").arg( foundIndices[foundIndices.size() - 1].absoluteFilePath(), dependModules[i])); indexToAdd = foundIndices[foundIndices.size() - 1].absoluteFilePath(); } else if (foundIndices.size() == 1) { indexToAdd = foundIndices[0].absoluteFilePath(); } if (!indexToAdd.isEmpty()) { if (!indexFiles.contains(indexToAdd)) indexFiles << indexToAdd; } else { Location::null.warning(QString("\"%1\" Cannot locate index file for dependency \"%2\"").arg( config.getString(CONFIG_PROJECT), dependModules[i])); } } } else { Location::null.warning(QLatin1String("Dependent modules specified, but no index directories were set. There will probably be errors for missing links.")); } } qdb->readIndexes(indexFiles); } /*! Processes the qdoc config file \a fileName. This is the controller for all of qdoc. */ static void processQdocconfFile(const QString &fileName)