Warning: That file was not part of the compilation database. It may have many parsing errors.

1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*
43 main.cpp
44*/
45
46#include <qglobal.h>
47#include <stdlib.h>
48#include "codemarker.h"
49#include "codeparser.h"
50#include "config.h"
51#include "cppcodemarker.h"
52#include "cppcodeparser.h"
53#include "ditaxmlgenerator.h"
54#include "doc.h"
55#include "htmlgenerator.h"
56#include "jscodemarker.h"
57#include "plaincodemarker.h"
58#include "puredocparser.h"
59#include "qmlcodemarker.h"
60#include "qmlcodeparser.h"
61#include "tokenizer.h"
62#include "tree.h"
63#include <qdebug.h>
64
65#include "qtranslator.h"
66#ifndef QT_BOOTSTRAPPED
67# include "qcoreapplication.h"
68#endif
69
70QT_BEGIN_NAMESPACE
71
72/*
73 The default indent for code is 4.
74 The default value for false is 0.
75 The default language is c++.
76 The default output format is html.
77 The default tab size is 8.
78 And those are all the default values for configuration variables.
79 */
80static const struct {
81 const char *key;
82 const char *value;
83} defaults[] = {
84 { CONFIG_CODEINDENT, "4" },
85 { CONFIG_FALSEHOODS, "0" },
86 { CONFIG_LANGUAGE, "Cpp" },
87 { CONFIG_OUTPUTFORMATS, "HTML" },
88 { CONFIG_TABSIZE, "8" },
89 { 0, 0 }
90};
91
92static bool slow = false;
93static bool showInternal = false;
94static bool obsoleteLinks = false;
95static QStringList defines;
96static QHash<QString, Tree *> trees;
97
98/*!
99 Print the help message to \c stdout.
100 */
101static void printHelp()
102{
103 Location::information(tr("Usage: qdoc [options] file1.qdocconf ...\n"
104 "Options:\n"
105 " -help "
106 "Display this information and exit\n"
107 " -version "
108 "Display version of qdoc and exit\n"
109 " -D<name> "
110 "Define <name> as a macro while parsing sources\n"
111 " -slow "
112 "Turn on features that slow down qdoc\n"
113 " -showinternal "
114 "Include stuff marked internal\n"
115 " -obsoletelinks "
116 "Report links from obsolete items to non-obsolete items") );
117}
118
119/*!
120 Prints the qdoc version number to stdout.
121 */
122static void printVersion()
123{
124 QString s = tr("qdoc version %1").arg(QT_VERSION_STR);
125 Location::information(s);
126}
127
128/*!
129 Processes the qdoc config file \a fileName. This is the
130 controller for all of qdoc.
131 */
132static void processQdocconfFile(const QString &fileName)
133{
134#ifndef QT_NO_TRANSLATION
135 QList<QTranslator *> translators;
136#endif
137
138 /*
139 The Config instance represents the configuration data for qdoc.
140 All the other classes are initialized with the config. Here we
141 initialize the configuration with some default values.
142 */
143 Config config(tr("qdoc"));
144 int i = 0;
145 while (defaults[i].key) {
146 config.setStringList(defaults[i].key,
147 QStringList() << defaults[i].value);
148 ++i;
149 }
150 config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(slow ? "true" : "false"));
151 config.setStringList(CONFIG_SHOWINTERNAL,
152 QStringList(showInternal ? "true" : "false"));
153 config.setStringList(CONFIG_OBSOLETELINKS,
154 QStringList(obsoleteLinks ? "true" : "false"));
155
156 /*
157 With the default configuration values in place, load
158 the qdoc configuration file. Note that the configuration
159 file may include other configuration files.
160
161 The Location class keeps track of the current location
162 in the file being processed, mainly for error reporting
163 purposes.
164 */
165 Location::initialize(config);
166 config.load(fileName);
167
168 /*
169 Add the defines to the configuration variables.
170 */
171 QStringList defs = defines + config.getStringList(CONFIG_DEFINES);
172 config.setStringList(CONFIG_DEFINES,defs);
173 Location::terminate();
174
175 QString prevCurrentDir = QDir::currentPath();
176 QString dir = QFileInfo(fileName).path();
177 if (!dir.isEmpty())
178 QDir::setCurrent(dir);
179
180 /*
181 Initialize all the classes and data structures with the
182 qdoc configuration.
183 */
184 Location::initialize(config);
185 Tokenizer::initialize(config);
186 Doc::initialize(config);
187 CodeMarker::initialize(config);
188 CodeParser::initialize(config);
189 Generator::initialize(config);
190
191#ifndef QT_NO_TRANSLATION
192 /*
193 Load the language translators, if the configuration specifies any.
194 */
195 QStringList fileNames = config.getStringList(CONFIG_TRANSLATORS);
196 QStringList::Iterator fn = fileNames.begin();
197 while (fn != fileNames.end()) {
198 QTranslator *translator = new QTranslator(0);
199 if (!translator->load(*fn))
200 config.lastLocation().error(tr("Cannot load translator '%1'")
201 .arg(*fn));
202 QCoreApplication::instance()->installTranslator(translator);
203 translators.append(translator);
204 ++fn;
205 }
206#endif
207
208 //QSet<QString> outputLanguages = config.getStringSet(CONFIG_OUTPUTLANGUAGES);
209
210 /*
211 Get the source language (Cpp) from the configuration
212 and the location in the configuration file where the
213 source language was set.
214 */
215 QString lang = config.getString(CONFIG_LANGUAGE);
216 Location langLocation = config.lastLocation();
217
218 /*
219 Initialize the tree where all the parsed sources will be stored.
220 The tree gets built as the source files are parsed, and then the
221 documentation output is generated by traversing the tree.
222 */
223 Tree *tree = new Tree;
224 tree->setVersion(config.getString(CONFIG_VERSION));
225
226 /*
227 By default, the only output format is HTML.
228 */
229 QSet<QString> outputFormats = config.getStringSet(CONFIG_OUTPUTFORMATS);
230 Location outputFormatsLocation = config.lastLocation();
231
232 /*
233 Read some XML indexes containing definitions from other documentation sets.
234 */
235 QStringList indexFiles = config.getStringList(CONFIG_INDEXES);
236 tree->readIndexes(indexFiles);
237
238#if 0
239 /*
240 I think we won't beusing this...
241
242 Read the list of DITA excluded directories.
243 */
244 QSet<QString> ditaExcludedDirs;
245 QStringList ditaExcludedDirsList = config.getStringList("dita.metadata.excludedirs");
246 foreach (const QString &t, ditaExcludedDirsList)
247 ditaExcludedDirs.insert(QDir::fromNativeSeparators(t));
248
249 if (!ditaExcludedDirs.isEmpty()) {
250 QSet<QString>::iterator i = ditaExcludedDirs.begin();
251 while (i != ditaExcludedDirs.end()) {
252 qDebug() << "DITA EXCLUDED DIR:" << (*i);
253 ++i;
254 }
255 }
256#endif
257
258 /*
259 Read the list of excluded directories.
260 */
261 QSet<QString> excludedDirs;
262 QStringList excludedDirsList = config.getStringList(CONFIG_EXCLUDEDIRS);
263 foreach (const QString &excludeDir, excludedDirsList)
264 excludedDirs.insert(QDir::fromNativeSeparators(excludeDir));
265
266 /*
267 Get all the header files: "*.ch *.h *.h++ *.hh *.hpp *.hxx"
268 Put them in a set.
269 */
270 QSet<QString> headers = QSet<QString>::fromList(
271 config.getAllFiles(CONFIG_HEADERS, CONFIG_HEADERDIRS, excludedDirs));
272
273 /*
274 Get all the source text files: "*.cpp *.qdoc *.mm"
275 Put them in a set.
276 */
277 QSet<QString> sources = QSet<QString>::fromList(
278 config.getAllFiles(CONFIG_SOURCES, CONFIG_SOURCEDIRS, excludedDirs));
279
280 /*
281 Parse each header file in the set using the appropriate parser and add it
282 to the big tree.
283 */
284 QSet<CodeParser *> usedParsers;
285
286 QSet<QString>::ConstIterator h = headers.begin();
287 while (h != headers.end()) {
288 CodeParser *codeParser = CodeParser::parserForHeaderFile(*h);
289 if (codeParser) {
290 codeParser->parseHeaderFile(config.location(), *h, tree);
291 usedParsers.insert(codeParser);
292 }
293 ++h;
294 }
295
296 foreach (CodeParser *codeParser, usedParsers)
297 codeParser->doneParsingHeaderFiles(tree);
298
299 usedParsers.clear();
300 /*
301 Parse each source text file in the set using the appropriate parser and
302 add it to the big tree.
303 */
304 QSet<QString>::ConstIterator s = sources.begin();
305 while (s != sources.end()) {
306 CodeParser *codeParser = CodeParser::parserForSourceFile(*s);
307 if (codeParser) {
308 codeParser->parseSourceFile(config.location(), *s, tree);
309 usedParsers.insert(codeParser);
310 }
311 ++s;
312 }
313
314 foreach (CodeParser *codeParser, usedParsers)
315 codeParser->doneParsingSourceFiles(tree);
316
317 /*
318 Now the big tree has been built from all the header and
319 source files. Resolve all the class names, function names,
320 targets, URLs, links, and other stuff that needs resolving.
321 */
322 tree->resolveGroups();
323 tree->resolveTargets();
324
325 /*
326 Now the tree has been built, and all the stuff that needed
327 resolving has been resolved. Now it is time to traverse
328 the big tree and generate the documentation output.
329 */
330 QSet<QString>::ConstIterator of = outputFormats.begin();
331 while (of != outputFormats.end()) {
332 Generator *generator = Generator::generatorForFormat(*of);
333 if (generator == 0)
334 outputFormatsLocation.fatal(tr("Unknown output format '%1'")
335 .arg(*of));
336 generator->generateTree(tree);
337 ++of;
338 }
339
340 /*
341 Generate the XML tag file, if it was requested.
342 */
343 QString tagFile = config.getString(CONFIG_TAGFILE);
344 if (!tagFile.isEmpty()) {
345 tree->generateTagFile(tagFile);
346 }
347
348 tree->setVersion("");
349 Generator::terminate();
350 CodeParser::terminate();
351 CodeMarker::terminate();
352 Doc::terminate();
353 Tokenizer::terminate();
354 Location::terminate();
355 QDir::setCurrent(prevCurrentDir);
356
357#ifndef QT_NO_TRANSLATION
358 qDeleteAll(translators);
359#endif
360#ifdef DEBUG_SHUTDOWN_CRASH
361 qDebug() << "main(): Delete tree";
362#endif
363 delete tree;
364#ifdef DEBUG_SHUTDOWN_CRASH
365 qDebug() << "main(): Tree deleted";
366#endif
367}
368
369QT_END_NAMESPACE
370
371int main(int argc, char **argv)
372{
373 QT_USE_NAMESPACE
374
375#ifndef QT_BOOTSTRAPPED
376 QCoreApplication app(argc, argv);
377#endif
378
379 /*
380 Create code parsers for the languages to be parsed,
381 and create a tree for C++.
382 */
383 CppCodeParser cppParser;
384 QmlCodeParser qmlParser;
385 PureDocParser docParser;
386
387 /*
388 Create code markers for plain text and C++.
389 */
390 PlainCodeMarker plainMarker;
391 CppCodeMarker cppMarker;
392 JsCodeMarker jsMarker;
393 QmlCodeMarker qmlMarker;
394
395 HtmlGenerator htmlGenerator;
396 DitaXmlGenerator ditaxmlGenerator;
397
398 QStringList qdocFiles;
399 QString opt;
400 int i = 1;
401
402 while (i < argc) {
403 opt = argv[i++];
404
405 if (opt == "-help") {
406 printHelp();
407 return EXIT_SUCCESS;
408 }
409 else if (opt == "-version") {
410 printVersion();
411 return EXIT_SUCCESS;
412 }
413 else if (opt == "--") {
414 while (i < argc)
415 qdocFiles.append(argv[i++]);
416 }
417 else if (opt.startsWith("-D")) {
418 QString define = opt.mid(2);
419 defines += define;
420 }
421 else if (opt == "-slow") {
422 slow = true;
423 }
424 else if (opt == "-showinternal") {
425 showInternal = true;
426 }
427 else if (opt == "-obsoletelinks") {
428 obsoleteLinks = true;
429 }
430 else {
431 qdocFiles.append(opt);
432 }
433 }
434
435 if (qdocFiles.isEmpty()) {
436 printHelp();
437 return EXIT_FAILURE;
438 }
439
440 /*
441 Main loop.
442 */
443 foreach (QString qf, qdocFiles) {
444 //qDebug() << "PROCESSING:" << qf;
445 processQdocconfFile(qf);
446 }
447
448 qDeleteAll(trees);
449 return EXIT_SUCCESS;
450}
451
452

Warning: That file was not part of the compilation database. It may have many parsing errors.