QFile::readData: Simplify code
[qt-netbsd.git] / tools / qdoc3 / main.cpp
blob3d0106d0f171260dde3e346d3073cec047144108
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the tools applications of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
43 main.cpp
46 #include <qglobal.h>
47 #include <QtCore>
48 #include <stdlib.h>
49 #include "apigenerator.h"
50 #include "codemarker.h"
51 #include "codeparser.h"
52 #include "config.h"
53 #include "cppcodemarker.h"
54 #include "cppcodeparser.h"
55 #include "cpptoqsconverter.h"
56 #include "doc.h"
57 #include "htmlgenerator.h"
58 #include "jambiapiparser.h"
59 #include "javacodemarker.h"
60 #include "javadocgenerator.h"
61 #include "linguistgenerator.h"
62 #include "loutgenerator.h"
63 #include "mangenerator.h"
64 #include "plaincodemarker.h"
65 #include "polyarchiveextractor.h"
66 #include "polyuncompressor.h"
67 #include "qsakernelparser.h"
68 #include "qscodemarker.h"
69 #include "qscodeparser.h"
70 #include "sgmlgenerator.h"
71 #include "webxmlgenerator.h"
72 #include "tokenizer.h"
73 #include "tree.h"
75 QT_BEGIN_NAMESPACE
78 The default indent for code is 4.
79 The default value for false is 0.
80 The default language is c++.
81 The default output format is html.
82 The default tab size is 8.
83 And those are all the default values for configuration variables.
85 static const struct {
86 const char *key;
87 const char *value;
88 } defaults[] = {
89 { CONFIG_CODEINDENT, "4" },
90 { CONFIG_FALSEHOODS, "0" },
91 { CONFIG_LANGUAGE, "Cpp" },
92 { CONFIG_OUTPUTFORMATS, "HTML" },
93 { CONFIG_TABSIZE, "8" },
94 { 0, 0 }
97 static bool slow = false;
98 static bool showInternal = false;
99 static bool obsoleteLinks = false;
100 static QStringList defines;
101 static QHash<QString, Tree *> trees;
104 Find the Tree for language \a lang and return a pointer to it.
105 If there is no Tree for language \a lang in the Tree table, add
106 a new one. The Tree table is indexed by \a lang strings.
108 static Tree* treeForLanguage(const QString &lang)
110 Tree* tree = trees.value(lang);
111 if (tree == 0) {
112 tree = new Tree;
113 trees.insert( lang, tree );
115 return tree;
119 Print the help message to \c stdout.
121 static void printHelp()
123 Location::information(tr("Usage: qdoc [options] file1.qdocconf ...\n"
124 "Options:\n"
125 " -help "
126 "Display this information and exit\n"
127 " -version "
128 "Display version of qdoc and exit\n"
129 " -D<name> "
130 "Define <name> as a macro while parsing sources\n"
131 " -slow "
132 "Turn on features that slow down qdoc\n"
133 " -showinternal "
134 "Include stuff marked internal\n"
135 " -obsoletelinks "
136 "Report links from obsolete items to non-obsolete items") );
140 Prints the qdoc version number to stdout.
142 static void printVersion()
144 QString s = QString(tr("qdoc version ")) + QString(QT_VERSION_STR);
145 Location::information(s);
149 Processes the qdoc config file \a fileName. This is the
150 controller for all of qdoc.
152 static void processQdocconfFile(const QString &fileName)
154 QList<QTranslator *> translators;
157 The Config instance represents the configuration data for qdoc.
158 All the other classes are initialized with the config. Here we
159 initialize the configuration with some default values.
161 Config config(tr("qdoc"));
162 int i = 0;
163 while (defaults[i].key) {
164 config.setStringList(defaults[i].key,
165 QStringList() << defaults[i].value);
166 ++i;
168 config.setStringList(CONFIG_SLOW, QStringList(slow ? "true" : "false"));
169 config.setStringList(CONFIG_SHOWINTERNAL,
170 QStringList(showInternal ? "true" : "false"));
171 config.setStringList(CONFIG_OBSOLETELINKS,
172 QStringList(obsoleteLinks ? "true" : "false"));
175 With the default configuration values in place, load
176 the qdoc configuration file. Note that the configuration
177 file may include other configuration files.
179 The Location class keeps track of the current location
180 in the file being processed, mainly for error reporting
181 purposes.
183 Location::initialize(config);
184 config.load(fileName);
187 Add the defines to the configuration variables.
189 QStringList defs = defines + config.getStringList(CONFIG_DEFINES);
190 config.setStringList(CONFIG_DEFINES,defs);
191 Location::terminate();
193 QString prevCurrentDir = QDir::currentPath();
194 QString dir = QFileInfo(fileName).path();
195 if (!dir.isEmpty())
196 QDir::setCurrent(dir);
199 Initialize all the classes and data structures with the
200 qdoc configuration.
202 Location::initialize(config);
203 Tokenizer::initialize(config);
204 Doc::initialize(config);
205 CppToQsConverter::initialize(config);
206 CodeMarker::initialize(config);
207 CodeParser::initialize(config);
208 Generator::initialize(config);
211 Load the language translators, if the configuration specifies any.
213 QStringList fileNames = config.getStringList(CONFIG_TRANSLATORS);
214 QStringList::Iterator fn = fileNames.begin();
215 while (fn != fileNames.end()) {
216 QTranslator *translator = new QTranslator(0);
217 if (!translator->load(*fn))
218 config.lastLocation().error(tr("Cannot load translator '%1'")
219 .arg(*fn));
220 QCoreApplication::instance()->installTranslator(translator);
221 translators.append(translator);
222 ++fn;
225 //QSet<QString> outputLanguages = config.getStringSet(CONFIG_OUTPUTLANGUAGES);
228 Get the source language (Cpp) from the configuration
229 and the location in the configuration file where the
230 source language was set.
232 QString lang = config.getString(CONFIG_LANGUAGE);
233 Location langLocation = config.lastLocation();
236 Initialize the tree where all the parsed sources will be stored.
237 The tree gets built as the source files are parsed, and then the
238 documentation output is generated by traversing the tree.
240 Tree *tree = new Tree;
241 tree->setVersion(config.getString(CONFIG_VERSION));
244 There must be a code parser for the source code language, e.g. C++.
245 If there isn't one, give up.
247 CodeParser *codeParser = CodeParser::parserForLanguage(lang);
248 if (codeParser == 0)
249 config.lastLocation().fatal(tr("Cannot parse programming language '%1'").arg(lang));
252 By default, the only output format is HTML.
254 QSet<QString> outputFormats = config.getStringSet(CONFIG_OUTPUTFORMATS);
255 Location outputFormatsLocation = config.lastLocation();
258 There must be a code marker for the source code language, e.g. C++.
259 If there isn't one, give up.
261 CodeMarker *marker = CodeMarker::markerForLanguage(lang);
262 if (!marker && !outputFormats.isEmpty())
263 langLocation.fatal(tr("Cannot output documentation for programming language '%1'").arg(lang));
266 Read some XML indexes. What are they???
268 QStringList indexFiles = config.getStringList(CONFIG_INDEXES);
269 tree->readIndexes(indexFiles);
272 Get all the header files: "*.ch *.h *.h++ *.hh *.hpp *.hxx"
273 Put them in a set.
275 QSet<QString> excludedDirs;
276 QStringList excludedDirsList = config.getStringList(CONFIG_EXCLUDEDIRS);
277 foreach (const QString &excludeDir, excludedDirsList)
278 excludedDirs.insert(QDir::fromNativeSeparators(excludeDir));
279 QSet<QString> headers = QSet<QString>::fromList(
280 config.getAllFiles(CONFIG_HEADERS, CONFIG_HEADERDIRS,
281 codeParser->headerFileNameFilter(),
282 excludedDirs));
285 Parse each header file in the set and add it to the big tree.
287 QSet<QString>::ConstIterator h = headers.begin();
288 while (h != headers.end()) {
289 codeParser->parseHeaderFile(config.location(), *h, tree);
290 ++h;
292 codeParser->doneParsingHeaderFiles(tree);
295 Get all the source text files: "*.cpp *.qdoc *.mm"
296 Put them in a set.
298 QSet<QString> sources = QSet<QString>::fromList(
299 config.getAllFiles(CONFIG_SOURCES, CONFIG_SOURCEDIRS,
300 codeParser->sourceFileNameFilter(),
301 excludedDirs));
304 Parse each source text file in the set and add it to the big tree.
306 QSet<QString>::ConstIterator s = sources.begin();
307 while (s != sources.end()) {
308 codeParser->parseSourceFile(config.location(), *s, tree);
309 ++s;
311 codeParser->doneParsingSourceFiles(tree);
314 Now the big tree has been built from all the header and
315 source files. Resolve all the class names, function names,
316 targets, URLs, links, and other stuff that needs resolving.
318 tree->resolveGroups();
319 tree->resolveTargets();
322 Now the tree has been built, and all the stuff that needed
323 resolving has been resolved. Now it is time to traverse
324 the big tree and generate the documentation output.
326 QSet<QString>::ConstIterator of = outputFormats.begin();
327 while (of != outputFormats.end()) {
328 Generator *generator = Generator::generatorForFormat(*of);
329 if (generator == 0)
330 outputFormatsLocation.fatal(tr("Unknown output format '%1'")
331 .arg(*of));
332 generator->generateTree(tree, marker);
333 ++of;
337 Generate the XML tag file, if it was requested.
339 QString tagFile = config.getString(CONFIG_TAGFILE);
340 if (!tagFile.isEmpty())
341 tree->generateTagFile(tagFile);
343 tree->setVersion("");
344 Generator::terminate();
345 CodeParser::terminate();
346 CodeMarker::terminate();
347 CppToQsConverter::terminate();
348 Doc::terminate();
349 Tokenizer::terminate();
350 Location::terminate();
351 QDir::setCurrent(prevCurrentDir);
353 foreach (QTranslator *translator, translators)
354 delete translator;
355 delete tree;
358 QT_END_NAMESPACE
360 int main(int argc, char **argv)
362 QT_USE_NAMESPACE
364 QCoreApplication app(argc, argv);
365 QString cf = "qsauncompress \1 \2";
366 PolyArchiveExtractor qsaExtractor(QStringList() << "qsa",cf);
367 cf = "tar -C \2 -xf \1";
368 PolyArchiveExtractor tarExtractor(QStringList() << "tar",cf);
369 cf = "tar -C \2 -Zxf \1";
370 PolyArchiveExtractor tazExtractor(QStringList() << "taz",cf);
371 cf = "tar -C \2 -jxf \1";
372 PolyArchiveExtractor tbz2Extractor(QStringList() << "tbz" << "tbz2",cf);
373 cf = "tar -C \2 -zxf \1";
374 PolyArchiveExtractor tgzExtractor(QStringList() << "tgz",cf);
375 cf = "unzip \1 -d \2";
376 PolyArchiveExtractor zipExtractor(QStringList() << "zip",cf);
377 cf = "bunzip2 -c \1 > \2";
378 PolyUncompressor bz2Uncompressor(QStringList() << "bz" << "bz2",cf);
379 cf = "gunzip -c \1 > \2";
380 PolyUncompressor gzAndZUncompressor(QStringList() << "gz" << "z" << "Z",cf);
381 cf = "unzip -c \1 > \2";
382 PolyUncompressor zipUncompressor(QStringList() << "zip",cf);
385 Create code parsers for the languages to be parsed,
386 and create a tree for C++.
388 CppCodeParser cppParser;
389 Tree *cppTree = treeForLanguage(cppParser.language());
391 QsCodeParser qsParser(cppTree);
392 QsaKernelParser qsaKernelParser(cppTree);
393 JambiApiParser jambiParser(cppTree);
396 Create code markers for plain text, C++, Java, and qs.
398 PlainCodeMarker plainMarker;
399 CppCodeMarker cppMarker;
400 JavaCodeMarker javaMarker;
401 QsCodeMarker qsMarker;
403 ApiGenerator apiGenerator;
404 HtmlGenerator htmlGenerator;
405 JavadocGenerator javadocGenerator;
406 LinguistGenerator linguistGenerator;
407 LoutGenerator loutGenerator;
408 ManGenerator manGenerator;
409 SgmlGenerator smglGenerator;
410 WebXMLGenerator webxmlGenerator;
412 QStringList qdocFiles;
413 QString opt;
414 int i = 1;
416 while (i < argc) {
417 opt = argv[i++];
419 if (opt == "-help") {
420 printHelp();
421 return EXIT_SUCCESS;
423 else if (opt == "-version") {
424 printVersion();
425 return EXIT_SUCCESS;
427 else if (opt == "--") {
428 while (i < argc)
429 qdocFiles.append(argv[i++]);
431 else if (opt.startsWith("-D")) {
432 QString define = opt.mid(2);
433 defines += define;
435 else if (opt == "-slow") {
436 slow = true;
438 else if (opt == "-showinternal") {
439 showInternal = true;
441 else if (opt == "-obsoletelinks") {
442 obsoleteLinks = true;
444 else {
445 qdocFiles.append(opt);
449 if (qdocFiles.isEmpty()) {
450 printHelp();
451 return EXIT_FAILURE;
455 Main loop.
457 foreach (QString qf, qdocFiles)
458 processQdocconfFile(qf);
460 qDeleteAll(trees);
461 return EXIT_SUCCESS;