source: trunk/tools/qdoc3/main.cpp@ 1077

Last change on this file since 1077 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 15.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the tools applications of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*
43 main.cpp
44*/
45
46#include <qglobal.h>
47#include <stdlib.h>
48#include "apigenerator.h"
49#include "codemarker.h"
50#include "codeparser.h"
51#include "config.h"
52#include "cppcodemarker.h"
53#include "cppcodeparser.h"
54#include "cpptoqsconverter.h"
55#include "doc.h"
56#include "htmlgenerator.h"
57#include "jambiapiparser.h"
58#include "javacodemarker.h"
59#include "javadocgenerator.h"
60#include "linguistgenerator.h"
61#include "loutgenerator.h"
62#include "mangenerator.h"
63#include "plaincodemarker.h"
64#include "polyarchiveextractor.h"
65#include "polyuncompressor.h"
66#include "qsakernelparser.h"
67#include "qscodemarker.h"
68#include "qscodeparser.h"
69#include "sgmlgenerator.h"
70#include "webxmlgenerator.h"
71#include "ditaxmlgenerator.h"
72#include "tokenizer.h"
73#include "tree.h"
74#include <qdebug.h>
75
76#include "qtranslator.h"
77#ifndef QT_BOOTSTRAPPED
78# include "qcoreapplication.h"
79#endif
80
81QT_BEGIN_NAMESPACE
82
83/*
84 The default indent for code is 4.
85 The default value for false is 0.
86 The default language is c++.
87 The default output format is html.
88 The default tab size is 8.
89 And those are all the default values for configuration variables.
90 */
91static const struct {
92 const char *key;
93 const char *value;
94} defaults[] = {
95 { CONFIG_CODEINDENT, "4" },
96 { CONFIG_FALSEHOODS, "0" },
97 { CONFIG_LANGUAGE, "Cpp" },
98 { CONFIG_OUTPUTFORMATS, "HTML" },
99 { CONFIG_TABSIZE, "8" },
100 { 0, 0 }
101};
102
103static bool slow = false;
104static bool showInternal = false;
105static bool obsoleteLinks = false;
106static QStringList defines;
107static QHash<QString, Tree *> trees;
108static QString appArg; // application
109
110/*!
111 Find the Tree for language \a lang and return a pointer to it.
112 If there is no Tree for language \a lang in the Tree table, add
113 a new one. The Tree table is indexed by \a lang strings.
114 */
115static Tree* treeForLanguage(const QString &lang)
116{
117 Tree* tree = trees.value(lang);
118 if (tree == 0) {
119 tree = new Tree;
120 trees.insert( lang, tree );
121 }
122 return tree;
123}
124
125/*!
126 Print the help message to \c stdout.
127 */
128static void printHelp()
129{
130 Location::information(tr("Usage: qdoc [options] file1.qdocconf ...\n"
131 "Options:\n"
132 " -help "
133 "Display this information and exit\n"
134 " -version "
135 "Display version of qdoc and exit\n"
136 " -D<name> "
137 "Define <name> as a macro while parsing sources\n"
138 " -slow "
139 "Turn on features that slow down qdoc\n"
140 " -showinternal "
141 "Include stuff marked internal\n"
142 " -obsoletelinks "
143 "Report links from obsolete items to non-obsolete items") );
144}
145
146/*!
147 Prints the qdoc version number to stdout.
148 */
149static void printVersion()
150{
151 QString s = tr("qdoc version %1").arg(QT_VERSION_STR);
152 Location::information(s);
153}
154
155/*!
156 Processes the qdoc config file \a fileName. This is the
157 controller for all of qdoc.
158 */
159static void processQdocconfFile(const QString &fileName)
160{
161#ifndef QT_NO_TRANSLATION
162 QList<QTranslator *> translators;
163#endif
164
165 /*
166 The Config instance represents the configuration data for qdoc.
167 All the other classes are initialized with the config. Here we
168 initialize the configuration with some default values.
169 */
170 Config config(tr("qdoc"));
171 int i = 0;
172 while (defaults[i].key) {
173 config.setStringList(defaults[i].key,
174 QStringList() << defaults[i].value);
175 ++i;
176 }
177 config.setStringList(CONFIG_SLOW, QStringList(slow ? "true" : "false"));
178 config.setStringList(CONFIG_SHOWINTERNAL,
179 QStringList(showInternal ? "true" : "false"));
180 config.setStringList(CONFIG_OBSOLETELINKS,
181 QStringList(obsoleteLinks ? "true" : "false"));
182
183 /*
184 With the default configuration values in place, load
185 the qdoc configuration file. Note that the configuration
186 file may include other configuration files.
187
188 The Location class keeps track of the current location
189 in the file being processed, mainly for error reporting
190 purposes.
191 */
192 Location::initialize(config);
193 config.load(fileName);
194
195 /*
196 Set the application to which qdoc will create the output.
197 The two applications are:
198
199 creator: additional formatting for viewing in
200 the Creator application.
201
202 online: full-featured online version with search and
203 links to Qt topics
204 */
205 if (appArg.isEmpty()) {
206 qDebug() << "Warning: Application flag not specified on"
207 << "command line. Options are -creator (default)"
208 << "and -online.";
209 appArg = "creator";
210 }
211 config.setStringList(CONFIG_APPLICATION, QStringList(appArg));
212
213 /*
214 Add the defines to the configuration variables.
215 */
216 QStringList defs = defines + config.getStringList(CONFIG_DEFINES);
217 config.setStringList(CONFIG_DEFINES,defs);
218 Location::terminate();
219
220 QString prevCurrentDir = QDir::currentPath();
221 QString dir = QFileInfo(fileName).path();
222 if (!dir.isEmpty())
223 QDir::setCurrent(dir);
224
225 /*
226 Initialize all the classes and data structures with the
227 qdoc configuration.
228 */
229 Location::initialize(config);
230 Tokenizer::initialize(config);
231 Doc::initialize(config);
232 CppToQsConverter::initialize(config);
233 CodeMarker::initialize(config);
234 CodeParser::initialize(config);
235 Generator::initialize(config);
236
237#ifndef QT_NO_TRANSLATION
238 /*
239 Load the language translators, if the configuration specifies any.
240 */
241 QStringList fileNames = config.getStringList(CONFIG_TRANSLATORS);
242 QStringList::Iterator fn = fileNames.begin();
243 while (fn != fileNames.end()) {
244 QTranslator *translator = new QTranslator(0);
245 if (!translator->load(*fn))
246 config.lastLocation().error(tr("Cannot load translator '%1'")
247 .arg(*fn));
248 QCoreApplication::instance()->installTranslator(translator);
249 translators.append(translator);
250 ++fn;
251 }
252#endif
253
254 //QSet<QString> outputLanguages = config.getStringSet(CONFIG_OUTPUTLANGUAGES);
255
256 /*
257 Get the source language (Cpp) from the configuration
258 and the location in the configuration file where the
259 source language was set.
260 */
261 QString lang = config.getString(CONFIG_LANGUAGE);
262 Location langLocation = config.lastLocation();
263
264 /*
265 Initialize the tree where all the parsed sources will be stored.
266 The tree gets built as the source files are parsed, and then the
267 documentation output is generated by traversing the tree.
268 */
269 Tree *tree = new Tree;
270 tree->setVersion(config.getString(CONFIG_VERSION));
271
272 /*
273 There must be a code parser for the source code language, e.g. C++.
274 If there isn't one, give up.
275 */
276 CodeParser *codeParser = CodeParser::parserForLanguage(lang);
277 if (codeParser == 0)
278 config.lastLocation().fatal(tr("Cannot parse programming language '%1'").arg(lang));
279
280 /*
281 By default, the only output format is HTML.
282 */
283 QSet<QString> outputFormats = config.getStringSet(CONFIG_OUTPUTFORMATS);
284 Location outputFormatsLocation = config.lastLocation();
285
286 /*
287 There must be a code marker for the source code language, e.g. C++.
288 If there isn't one, give up.
289 */
290 CodeMarker *marker = CodeMarker::markerForLanguage(lang);
291 if (!marker && !outputFormats.isEmpty())
292 langLocation.fatal(tr("Cannot output documentation for programming language '%1'").arg(lang));
293
294 /*
295 Read some XML indexes. What are they???
296 */
297 QStringList indexFiles = config.getStringList(CONFIG_INDEXES);
298 tree->readIndexes(indexFiles);
299
300 /*
301 Get all the header files: "*.ch *.h *.h++ *.hh *.hpp *.hxx"
302 Put them in a set.
303 */
304 QSet<QString> excludedDirs;
305 QStringList excludedDirsList = config.getStringList(CONFIG_EXCLUDEDIRS);
306 foreach (const QString &excludeDir, excludedDirsList)
307 excludedDirs.insert(QDir::fromNativeSeparators(excludeDir));
308 QSet<QString> headers = QSet<QString>::fromList(
309 config.getAllFiles(CONFIG_HEADERS, CONFIG_HEADERDIRS,
310 codeParser->headerFileNameFilter(),
311 excludedDirs));
312
313 /*
314 Parse each header file in the set and add it to the big tree.
315 */
316 QSet<QString>::ConstIterator h = headers.begin();
317 while (h != headers.end()) {
318 codeParser->parseHeaderFile(config.location(), *h, tree);
319 ++h;
320 }
321 codeParser->doneParsingHeaderFiles(tree);
322
323 /*
324 Get all the source text files: "*.cpp *.qdoc *.mm"
325 Put them in a set.
326 */
327 QSet<QString> sources = QSet<QString>::fromList(
328 config.getAllFiles(CONFIG_SOURCES, CONFIG_SOURCEDIRS,
329 codeParser->sourceFileNameFilter(),
330 excludedDirs));
331
332 /*
333 Parse each source text file in the set and add it to the big tree.
334 */
335 QSet<QString>::ConstIterator s = sources.begin();
336 while (s != sources.end()) {
337 codeParser->parseSourceFile(config.location(), *s, tree);
338 ++s;
339 }
340 codeParser->doneParsingSourceFiles(tree);
341
342 /*