I don't think this was intentional...
[qt-netbsd.git] / tools / qdoc3 / main.cpp
blobaac4ee8f5cf5dbbcd70ccbc1f1a6d2527dcc43a2
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 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.
340 QString tagFile = config.getString(CONFIG_TAGFILE);
341 if (!tagFile.isEmpty())
342 tree->generateTagFile(tagFile);
344 tree->setVersion("");
345 Generator::terminate();
346 CodeParser::terminate();
347 CodeMarker::terminate();
348 CppToQsConverter::terminate();
349 Doc::terminate();
350 Tokenizer::terminate();
351 Location::terminate();
352 QDir::setCurrent(prevCurrentDir);
354 foreach (QTranslator *translator, translators)
355 delete translator;
356 delete tree;
359 QT_END_NAMESPACE
361 int main(int argc, char **argv)
363 QT_USE_NAMESPACE
365 QCoreApplication app(argc, argv);
366 QString cf = "qsauncompress \1 \2";
367 PolyArchiveExtractor qsaExtractor(QStringList() << "qsa",cf);
368 cf = "tar -C \2 -xf \1";
369 PolyArchiveExtractor tarExtractor(QStringList() << "tar",cf);
370 cf = "tar -C \2 -Zxf \1";
371 PolyArchiveExtractor tazExtractor(QStringList() << "taz",cf);
372 cf = "tar -C \2 -jxf \1";
373 PolyArchiveExtractor tbz2Extractor(QStringList() << "tbz" << "tbz2",cf);
374 cf = "tar -C \2 -zxf \1";
375 PolyArchiveExtractor tgzExtractor(QStringList() << "tgz",cf);
376 cf = "unzip \1 -d \2";
377 PolyArchiveExtractor zipExtractor(QStringList() << "zip",cf);
378 cf = "bunzip2 -c \1 > \2";
379 PolyUncompressor bz2Uncompressor(QStringList() << "bz" << "bz2",cf);
380 cf = "gunzip -c \1 > \2";
381 PolyUncompressor gzAndZUncompressor(QStringList() << "gz" << "z" << "Z",cf);
382 cf = "unzip -c \1 > \2";
383 PolyUncompressor zipUncompressor(QStringList() << "zip",cf);
386 Create code parsers for the languages to be parsed,
387 and create a tree for C++.
389 CppCodeParser cppParser;
390 Tree *cppTree = treeForLanguage(cppParser.language());
392 QsCodeParser qsParser(cppTree);
393 QsaKernelParser qsaKernelParser(cppTree);
394 JambiApiParser jambiParser(cppTree);
397 Create code markers for plain text, C++, Java, and qs.
399 PlainCodeMarker plainMarker;
400 CppCodeMarker cppMarker;
401 JavaCodeMarker javaMarker;
402 QsCodeMarker qsMarker;
404 ApiGenerator apiGenerator;
405 HtmlGenerator htmlGenerator;
406 JavadocGenerator javadocGenerator;
407 LinguistGenerator linguistGenerator;
408 LoutGenerator loutGenerator;
409 ManGenerator manGenerator;
410 SgmlGenerator smglGenerator;
411 WebXMLGenerator webxmlGenerator;
413 QStringList qdocFiles;
414 QString opt;
415 int i = 1;
417 while (i < argc) {
418 opt = argv[i++];
420 if (opt == "-help") {
421 printHelp();
422 return EXIT_SUCCESS;
424 else if (opt == "-version") {
425 printVersion();
426 return EXIT_SUCCESS;
428 else if (opt == "--") {
429 while (i < argc)
430 qdocFiles.append(argv[i++]);
432 else if (opt.startsWith("-D")) {
433 QString define = opt.mid(2);
434 defines += define;
436 else if (opt == "-slow") {
437 slow = true;
439 else if (opt == "-showinternal") {
440 showInternal = true;
442 else if (opt == "-obsoletelinks") {
443 obsoleteLinks = true;
445 else {
446 qdocFiles.append(opt);
450 if (qdocFiles.isEmpty()) {
451 printHelp();
452 return EXIT_FAILURE;
456 Main loop.
458 foreach (QString qf, qdocFiles)
459 processQdocconfFile(qf);
461 qDeleteAll(trees);
462 return EXIT_SUCCESS;